从Object内部访问时,变量变为0

时间:2015-09-12 01:13:41

标签: javascript

我创建了一个像这样的对象:

var Object = function() {
    var value = 0;

    function do() {
        console.log(value);
    }

    return {
        do : do,
        value : value
    }
};
exports.Object = Object;

我从此对象外部调用do函数:

function call(object) {
    console.log(object.value);
    object.update();
}

我在播放器类之外将值设置为2.5。奇怪的是,当我执行代码时,控制台会记录下来:

2.5
0
2.5
0

所以似乎该类中的值为0,但是当我从外部访问它时为2.5。这是什么问题?

我的背景主要是Java,我对Javascript很新,所以也许我错过了一些微不足道的东西。

3 个答案:

答案 0 :(得分:3)

您已经创建了一个闭包:您返回了一个具有属性value的对象,但是当您更改时,闭包中的var value不会更改返回对象的value属性。

解释另一种方式,当你说new Object时,你会得到两个value,一个作为对象的属性返回,另一个是隐藏在闭包内的var object

尝试以下方法:

var Object = function() {
    this.value = 0;

    function do() {
        console.log(this.value);
    }

    return {
        do : do
    }
};

exports.Object = new Object;

可替换地:

var Object = function() {
    var value = 0;

    function do() {
        console.log(value);
    }

    return {
        do : do,
        getValue : function(){ return value; },
        setValue : function(val){ value = val; }
    }
};

exports.Object = Object;

答案 1 :(得分:2)

正如Josh所提到的,这是一个value vs reference问题,通常通过返回一个对象(因此通过引用)或包含{{1}等函数来解决。 }和getValue

对于第二个选项,您实际上可以重新编写函数并使用setValue,如下所示:

getters

此时,var Object = function() { var value = 0; function _do() { console.log(value); } function update(val) { value = val * .5; } return { do: _do, update: update, // Our fancy getter! get value() { return value; } } }; exports.Object = Object; 的行为与Object.value类似。

从星期五开始,让我们发疯,并添加我们的getValue

setter

然后你做了以下事情:

var Object = function() {
    var value = 0;

    function _do() {
        console.log(value);
    }
    return {
        do: _do,

        // Our fancy getters/setters!
        get value() {
            return value;
        },
        set value(val) {
            value = val * .5;
        }
    }
};
exports.Object = Object;

Defining Getters and Setters

Getter/Setter compatibility

答案 2 :(得分:1)

实际上,您的代码等同于

var Object = function() {
  var value = 0;

  function do() {
    console.log(value);
  }

  var res= {
    do : do,
    value : value
  }
  return res;
 };
exports.Object = Object; 

函数do()不会记录res.value。相反,它会记录函数Object的局部变量,这意味着您无法更改值do返回值。

如果您想记录res.value,可以尝试以下操作:

function do(){
    console.log(this.value);
}

但是我必须提一下其他的东西。 如果value是一个对象而不是文字。你可以轻松访问它。当ref传递对象时,闭包无法保护对象不被更改。

试试这个:

var Object = function() {
    var value = [0];

    function doSth() {
        console.log(value[0]);
    }

    var res= {
        do : doSth,
        value : value
    }
    return res;
};
exports.Object = Object;