increment
可以value
更改value
并且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
,而不是同一对象的属性。
这是否与increment和getValue方法是定义值的匿名函数的内部函数这一事实有关?
import shapeless.Generic
object FooBar {
case class Foo(a: String, b: Int, c: String)
case class Bar(x: String, y: Int, z: String)
def main(args: Array[String]): Unit = {
val genFoo = Generic[Foo]
val genBar = Generic[Bar]
println(genBar.from(genFoo.to(Foo("foobar", 5, "barfoo"))))
}
}
答案 0 :(得分:2)
var foo
创建一个变量,其范围限定为声明的函数。它可以作为foo
在该函数内的任何位置或在其中声明的其他函数中访问第一个功能。
myObject.foo
创建附加到对象的属性。它可以???.foo
访问,其中???
是对myObject
引用的对象的引用。您可以在任何可以找到对象引用的地方执行此操作。
属性不是变量。变量不是属性。 (例外情况是全局变量是全局变量(浏览器中的window
)对象的属性。
当您创建对象时,您说:
value: value,
但是会将value
变量的然后当前值复制到value
属性。
这是一个数字,不是参考。
更新value
变量时,value
属性不变。
答案 1 :(得分:1)
@Quentin's等其他答案已经解释了问题的彻底性。通过最低限度地修改当前的方法来纠正问题,这是一种正确的方法:
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

但是,此功能将是使用ES6 class
:
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

As was pointed out in comments,封闭和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