对increment
如何更改value
以及更改value
getValue
可以访问,但不能访问同一对象的属性感到困惑。
这是否与增量和 getValue 方法是定义值的匿名函数的内部函数这一事实有关?
var myObject = function() {
var value = 0;
return {
increment: function(inc){
value += typeof inc === 'number' ? inc : 1;
},
getValue: function(){
return value;
},
value: value,
};
}();
console.log(myObject.getValue()); // 0
myObject.increment(2);
console.log(myObject.getValue()); // 2
console.log(myObject.value); // 0
myObject.increment(2);
console.log(myObject.getValue()); // 4
var foo
创建一个变量,该变量的作用域为声明它的函数。它可以作为foo
在该函数中的任何位置访问,也可以在第一个函数内声明的另一个函数进行访问。
myObject.foo
创建一个附加到对象的属性。它可以作为???.foo
进行访问,其中???
是对myObject
引用的对象的引用。您可以在任何可以找到对象引用的地方执行此操作。
属性不是变量。变量不是属性。(例外情况是全局变量是全局(window
在浏览器中(对象的属性。
创建对象时,您说:
value: value,
但这会将value
变量的当前值复制到value
属性。
这是一个数字,不是参考。
更新value
变量时,value
属性保持不变。
像@Quentin这样的其他答案已经非常彻底地解释了这个问题是什么。不过,这是一种正确的方法,通过最少地修改您当前的方法来纠正问题:
var myObject = function() {
return {
increment: function(inc) {
this.value += typeof inc === 'number' ? inc : 1;
},
getValue: function() {
return this.value;
},
value: 0
};
}();
console.log(myObject.getValue()); // 0
myObject.increment(2);
console.log(myObject.getValue()); // 2
console.log(myObject.value); // 2
myObject.increment(2);
console.log(myObject.getValue()); // 4
console.log(myObject.value); // 4
但是,此功能将是使用 ES6class
的一个很好的例子:
class Counter {
constructor (value = 0) {
this.value = value
}
increment (amount = 1) {
this.value += amount
}
getValue () {
return this.value
}
}
let myObject = new Counter()
console.log(myObject.getValue()) // 0
myObject.increment(2)
console.log(myObject.getValue()) // 2
console.log(myObject.value) // 2
myObject.increment(2)
console.log(myObject.getValue()) // 4
console.log(myObject.value) // 4
正如评论中指出的那样,关闭和getValue()
似乎毫无意义。如果要允许value
访问作用域变量,并禁用对其进行修改,可以通过以下方式实现它:
var myObject = function() {
var value = 0;
return {
increment: function(inc) {
value += typeof inc === 'number' ? inc : 1;
},
getValue: function() {
return value;
},
get value() {
return value;
},
// disable setting it without throwing
set value(newValue) {
return value;
}
};
}();
console.log(myObject.getValue()); // 0
myObject.increment(2);
console.log(myObject.getValue()); // 2
console.log(myObject.value); // 2
// won't work
myObject.value = 4
// still 2
console.log(myObject.getValue()); // 2
console.log(myObject.value); // 2