Javascript 从对象内部访问时,变量变为0

Javascript 从对象内部访问时,变量变为0,javascript,Javascript,我创建了这样一个对象: var Object = function() { var value = 0; function do() { console.log(value); } return { do : do, value : value } }; exports.Object = Object; 我正在从该对象外部调用do函数: function call(object) { conso

我创建了这样一个对象:

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比较陌生,所以我可能错过了一些琐碎的东西

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

另一种解释是,当你说
newobject
时,你会得到两个
value
s一个作为对象的属性返回,另一个是隐藏在闭包中的
var对象

请尝试以下操作:

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

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

    return {
        do : do
    }
};

exports.Object = new Object;
function do(){
    console.log(this.value);
}
或者:

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;

正如Josh所提到的,这是一个
value
vs
reference
问题,通常通过返回一个对象(也就是通过引用)或包含
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;
然后你会做这样的事情:

Object.value; // Returns 0
Object.value = 5;
Object.value; // Returns 2.5
Object.do(); // Logs 2.5


事实上,您的代码相当于

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
,可以尝试以下操作:

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

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

    return {
        do : do
    }
};

exports.Object = new Object;
function do(){
    console.log(this.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; 

如果我不返回该值,这不意味着它不可访问吗?如果您创建一个
var
,那么该值对于闭包是“本地”的,并且您只能在闭包中修改它。如果您使用
this.value
,则该属性为“public”且可访问。第一个解决方案给了我一个错误:在我尝试记录它时未定义值。哎呀,修复了,
this.value
抱歉,您需要使用
新建
。我建议读一本JavaScript类的入门书,这会更简洁。谢谢你的详细解释。这里是星期六上午。所以有点太疯狂了;)