我认为我可以使用setter来更改闭包变量,但是当我直接访问变量时它没有改变。只有当我使用getter访问它时才能得到预期的重新赋值变量。是否在某个不同的范围内创建了第二个变量?这里发生了什么?
var obj = (function () {
var name = "one";
var setName = function(strName) {
name = strName;
};
var getName = function() {
return name;
};
return {
name: name,
setName: setName,
getName: getName
};
}());
obj.setName("two");
alert("obj.name is: " + obj.name); // Prints "one", but why not "two"?
alert("obj.getName() is: " + obj.getName()); // Prints "two" as I'd expect.
我已将上面的示例添加到fiddle
答案 0 :(得分:4)
您可以使用Object.defineProperty来完成您要执行的操作:
var obj = function () {
var name = "one";
var setName = function(strName) {
name = strName;
};
var getName = function() {
return name;
};
var result = {
setName: setName,
getName: getName
};
Object.defineProperty(result, 'name', { get: getName });
return result;
}();
obj.setName("two");
alert("obj.name is: " + obj.name); // two
alert("obj.getName() is: " + obj.getName()); // two
这是更新的jsfiddle:http://jsfiddle.net/potatosalad/8CsZ2/1/
答案 1 :(得分:4)
在您的代码中:
var obj = function () {
var name = "one";
此名称是本地变量对象的属性。这是 setName 和 getName 引用的那个。它在范围链上得到解决。
return {
name: name,
此名称是返回对象的属性,即它是一个不同的“名称”,并使用对象属性标识解析来解析(即,它与解析范围链上的标识符完全不同)。上面的行指定了局部变量名的当前值,这里没有闭包。
setName 和 getName 正在设置已关闭的变量, obj.name 未被这些函数修改。
答案 2 :(得分:2)
return {
name: name,
setName: setName,
getName: getName
};
在更新变量之前,正在创建上述对象,因此它将具有旧值
答案 3 :(得分:1)
您可能正在寻找的逻辑是:
var obj = function () {
var name = "one";
var setName = function(strName) {
this.name = strName;
};
var getName = function() {
return this.name;
};
return {
name: name,
setName: setName,
getName: getName
};
}();
obj.setName("two");
alert("obj.name is: " + obj.name); // one
alert("obj.getName() is: " + obj.getName()); // two
this
(this.name
)所代表的内容可能具有误导性。
调用方法obj.setName()
时,this.name
表示返回对象中的name属性,而不是顶部的第一个name
变量。
答案 4 :(得分:0)
在这种情况下,您将在对象中存储对闭包属性的引用。
当覆盖闭包变量的值时,对象属性仍将引用旧对象。