不在javascript中更新的对象中的变量

时间:2014-08-14 02:09:56

标签: javascript

我有一个初始化的对象,如

  var x = function(){
       var result = 5,
       clear = function(){
          result = 0;
        };
      return {
        result: result,
        clear: clear      
     }           
  }

我稍后使用x

创建var y = new x();的新实例

但是当我尝试设置value y.result = 5;并希望将result值清除为0时,我会致电y.clear();

但是,它没有将y.result重置为0 ...不确定原因?

我做错了什么?

2 个答案:

答案 0 :(得分:3)

在你的职能范围内:

var x = function(){
       var result = 5,
       clear = function(){
          result = 0;

此函数中的标识符 result 具有对外部函数中变量 result 的闭包(即外部执行上下文)。

        };
      return {
        result: result,

变量命名结果的值分配给名为result的对象属性

        clear: clear      
     }           
  }

所以稍后当你调用y.clear()时,你要设置闭包中保存的变量的值,它不会更新名为result的对象属性。

如果您希望 x 成为构造函数,那么:

function X() {
  this.result = 5;
  this.clear = function() {
    this.result = 0;
  }
}

现在:

var y = new X();
y.clear();
console.log(y.result); // 0

请注意,构造函数的约定是以大写字母开头的名称。您可以在MDN上了解有关如何使用 new 运算符的详情。

要利用ECMAScript继承,请将 clear 函数放在构造函数的原型上,以便所有实例都继承一个方法,而不是每个方法都有自己的方法:

function X() {
  this.result = 5;
}

X.prototype.clear = function() {
  this.result = 0;
}

答案 1 :(得分:1)

问题是数字是按值引用的。从result函数为clear变量赋值不会更改新result实例上x的值。

有几种方法可以解决这个问题:

  1. 将数据存储在this上,然后在构造函数和方法中修改它,我发现它更容易理解,更易读。这可能是你想要开始的:

    function x () {
        this.result = 5;
    }
    
    x.prototype.clear = function () {
        this.result = 0;
    }
    
    var z = new x();
    // z.result === 5
    z.clear()
    // z.result === 0;
    
  2. 在返回的对象上定义getter和setter,因此实例result将返回\ set closured variable:

    function x () {
        var result = 5;
    
        function clear () {
            result = 0;
        }
    
        var out = {
            clear: clear
        };
    
        Object.defineProperty(out, "result", {
            get: function () {
                return result;
            },
            set: function (value) {
                result = value;
            }
        });
    
        return out;
    }
    
    var z = new x();
    // z.result === 5
    z.clear()
    // z.result === 0;
    z.result = 10
    // z.result === 10;
    z.clear()
    // z.result === 0;