我可以使用显示模块模式在闭包中使用getter / setter作为变量吗?

时间:2013-05-02 03:45:03

标签: javascript revealing-module-pattern

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

5 个答案:

答案 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

thisthis.name)所代表的内容可能具有误导性。

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

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

答案 4 :(得分:0)

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

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