javascript模块模式返回对象引用?

时间:2016-08-04 15:39:00

标签: javascript

我的理解是对象通过引用传递。 我已经实现了模块模式如下。

git merge

我哪里错了? myModule.obj不是对内部obj var的引用吗?

编辑:结束了这个:

var myModule = (function(){
    var obj = {};

    return {
        obj: obj,
        updateObj: function(newObj) {
            obj = newObj;
        }
    }

}())

myModule.obj;   //  {}
myModule.updateObj({foo:'bar'});
myModule.obj;   //  still {}  :(

5 个答案:

答案 0 :(得分:5)

  

我哪里错了?

您正在为obj 变量分配新的引用,但这不是您的console代码正在查看的内容。它正在查看您要返回的对象的obj 属性中的引用。

  

myModule.obj不是对内部obj var?

的引用

没有。这样:

return {
    obj: obj
    // ...
}

对象引用从变量复制到属性,之后变量和属性之间没有链接。

在你的myModule之前创建updateObj之后,这就是你在内存中的内容(省略了一些不相关的细节):

 +−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+
 |  +−−−−−−−−−−−−−−−−−−−+                                     |
 +−>| execution context |                                     |
    +−−−−−−−−−−−−−−−−−−−+                                     |
    | obj: Ref11235     |−−−−−+                               |
    +−−−−−−−−−−−−−−−−−−−+     |                               |
                              |   +−−−−−−−−+                  |
    +−−−−−−−−−−−−−−−−−−−−−+   +−−>| object |                  |
    | variable "myModule" |   |   +−−−−−−−−+                  |
    +−−−−−−−−−−−−−−−−−−−−−+   |                               |
    | obj: Ref11235       |−−−+   +−−−−−−−−−−−−−−−−−−−−−−−+   |
    | updateObj: Ref88452 |−−−−−−>|  function             |   |
    +−−−−−−−−−−−−−−−−−−−−−+       +−−−−−−−−−−−−−−−−−−−−−−−+   |
                                  | environment: Ref71423 |−−−+
                                  | [[code]               |
                                  +−−−−−−−−−−−−−−−−−−−−−−−+

Ref11235只是该对象的对象引用值的plaeholder。 (类似地,Ref88452是函数的对象引用,Ref71423是对updateObj函数引用的幕后“EnvironmentRecord”对象的对象引用,因此它可以更新该环境的obj可变的。)

致电updateObj后,您已更改obj myModule属性中的引用,但这不会更改obj变量中的引用:

 +−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+
 |                                +−−−−−−−−+                  |
 |  +−−−−−−−−−−−−−−−−−−−+     +−−>| object |                  |
 +−>| execution context |     |   +−−−−−−−−+                  |
    +−−−−−−−−−−−−−−−−−−−+     |                               |
    | obj: Ref11235     |−−−−−+   +−−−−−−−−−−−−+              |
    +−−−−−−−−−−−−−−−−−−−+         |   object   |              |
                              +−−>+−−−−−−−−−−−−+              |
    +−−−−−−−−−−−−−−−−−−−−−+   |   | foo: "bar" |              |
    | variable "myModule" |   |   +−−−−−−−−−−−−+              |
    +−−−−−−−−−−−−−−−−−−−−−+   |                               |
    | obj: Ref65243       |−−−+   +−−−−−−−−−−−−−−−−−−−−−−−+   |
    | updateObj: Ref88452 |−−−−−−>|  function             |   |
    +−−−−−−−−−−−−−−−−−−−−−+       +−−−−−−−−−−−−−−−−−−−−−−−+   |
                                  | environment: Ref71123 |−−−+
                                  | [[code]               |
                                  +−−−−−−−−−−−−−−−−−−−−−−−+

唯一的变化是myModule.obj的值,现在引用一个新对象。

如果您更改updateObj以更新属性

updateObj: function(newObj) {
    this.obj = newObj;
}

...然后你会看到你期望的结果。 (此时完全取消obj变量可能是有意义的。)

答案 1 :(得分:3)

问题是obj内的updateObj没有引用模块内定义的obj变量。要引用与obj中相同的myModule,请使用this上下文。

this.obj = newObj;



var myModule = (function () {
    var obj = {};

    return {
        obj: obj,
        updateObj: function (newObj) {
            this.obj = newObj;
        }
    };
}());

console.log(myModule.obj);
myModule.updateObj({
    foo: 'bar'
});
console.log(myModule.obj);




答案 2 :(得分:2)

  

myModule.obj不是对内部obj var的引用吗?

不,不是。

var obj = {};创建一个对象并将其引用分配为obj的值。

obj: objobj(即引用)的值复制到另一个对象的obj属性。

obj = newObj使用对新对象的引用覆盖obj的值。这不会触及obj属性,因此它仍然是对第一个对象的引用。

答案 3 :(得分:1)

这个类似于下面的代码:

var a = {}, b=a;
a = {some:1};
alert(b.some);

这不起作用,导致排队a={some:1}您丢失了与b的链接。 希望它有意义!

答案 4 :(得分:0)

内存中有一些对象,并且有这些对象的地址。您的变量obj包含对象的地址。将obj变量分配给obj属性时,您将分配地址。然后你将obj变量中的地址覆盖到另一个对象,但在obj属性地址仍然是相同的。