1

我以为我可以使用 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.

我已将上面的示例添加到小提琴中

4

5 回答 5

4

在您的代码中:

var obj = function () {
  var name = "one";

名称是局部变量对象的属性。这是setNamegetName引用的那个。它在作用域链上得到解决。

  return {
    name: name,

名称是返回对象的一个​​属性,即它是一个不同的“名称”,并使用对象属性标识解析来解析(即与解析范围链上的标识符完全不同)。上面的行分配了局部变量名的当前值,这里没有闭包。

setNamegetName正在设置封闭变量,obj.name不会被这些函数修改。

于 2013-05-02T04:12:19.683 回答
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/

于 2013-05-02T03:52:03.177 回答
2
return {
    name: name,
    setName: setName,
    getName: getName
  };

上面的对象是在您更新变量之前创建的,因此它将具有旧值

于 2013-05-02T03:49:02.787 回答
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(in this.name) 代表的内容可能具有误导性。

obj.setName()调用该方法时,this.name表示返回对象中的 name 属性,而不是name顶部的第一个变量。

this关键字信息:https ://stackoverflow.com/a/3127440/1538708

于 2013-05-02T04:03:48.553 回答
0

在这种情况下,您正在对象中存储对闭包属性的引用。

当您覆盖闭包变量的值时,对象属性仍将引用旧对象。

于 2013-05-02T03:48:38.287 回答