首页 > 解决方案 > javascript:将函数分配给变量用未定义填充变量

问题描述

这有点基本,但让我有些头疼:

我将一个函数分配给一个变量,然后我从变量的第一个函数中调用一个函数。

当我将函数分配给变量时,它充满了未定义,所以当我调用内部函数时,我得到了错误:

未捕获的类型错误:无法读取未定义的属性“添加”

这是我正在处理的代码:

(function () {

  function Sum() {

    this.result = 0;

    this.getCurrentSum = function getCurrentSum() {
      return this.result;
    }

    this.add = function add(add_number) {
      this.result += add_number;
    }

  }

  var s1 = Sum();  // here s1 is undefined
  var s2 = Sum();  // here s2 is undefined

  s1.add(10);  // here cannot execute add of undefined crash
  s1.add(20);

  s2.add(30);
  s2.add(5);

  // must print 30
  console.log(s1.getCurrentSum());

  // must print 35
  console.log(s2.getCurrentSum());

}());

我可以更改 Sum 函数中的代码,但我无法更改其余代码

标签: javascriptobjectscope

解决方案


看起来你想Sum成为一个构造函数。您通过调用构造函数new,而不是直接调用。所以:

var s1 = new Sum();
var s2 = new Sum();

你进入和退出的原因undefineds1它在s2任何地方都不起作用,所以调用它的结果是 value 。但是当您使用 时,表达式的结果是创建的对象。newSumreturn xundefinednewnew

FWIW,还有另一个问题Sum:您this.在几个地方遗漏了(还有几个分号,尽管自动分号插入会为您添加它们):

function Sum() {
  this.result = 0;

  this.getCurrentSum = function getCurrentSum() {
    return this.result;
// −−−−−−−−^^^^^
  };

  this.add = function add(add_number) {
    this.result += add_number;
// −^^^^^
  };
}

JavaScript 不像 Java 或 C#,this.不是可选的。


在您问过的评论中:

如果我可以更改 Sum 函数或函数内部的任何内容,但我不能更改 var s1 = Sum(); 调用?

在这种情况下,您将创建Sum一个构建器函数并让它返回一个对象,如下所示:

function Sum() {
  return {
    result: 0,
    getCurrentSum: function getCurrentSum() {
      return this.result;
    },
    add: function add(add_number) {
      this.result += add_number;
    }
  };
}

现场示例:

(function () {

  function Sum() {
    return {
      result: 0,
      getCurrentSum: function getCurrentSum() {
        return this.result;
      },
      add: function add(add_number) {
        this.result += add_number;
      }
    };
  }

  var s1 = Sum();  // here s1 is undefined
  var s2 = Sum();  // here s2 is undefined

  s1.add(10);  // here cannot execute add of undefined crash
  s1.add(20);

  s2.add(30);
  s2.add(5);

  // must print 30
  console.log(s1.getCurrentSum());

  // must print 35
  console.log(s2.getCurrentSum());
})();

通常,构建器函数不会以大写字母开头(本质上是为构造器函数保留的),因此它的名称应该类似createSumbuildSum类似。

该版本Sum是用 ES5 级别的语法编写的(实际上它甚至是 ES3 级别的)。在 ES2015+ 中,它可能会更简洁一些:

// ES2015+ using method syntax
function Sum() {
  return {
    result: 0,
    getCurrentSum() {
      return this.result;
    },
    add(add_number) {
      this.result += add_number;
    }
  };
}

现场示例:

(function () {

  // ES2015+ using method syntax
  function Sum() {
    return {
      result: 0,
      getCurrentSum() {
        return this.result;
      },
      add(add_number) {
        this.result += add_number;
      }
    };
  }

  var s1 = Sum();  // here s1 is undefined
  var s2 = Sum();  // here s2 is undefined

  s1.add(10);  // here cannot execute add of undefined crash
  s1.add(20);

  s2.add(30);
  s2.add(5);

  // must print 30
  console.log(s1.getCurrentSum());

  // must print 35
  console.log(s2.getCurrentSum());
})();


推荐阅读