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

Bra*_*ent 0 javascript

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

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

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

}())

myModule.obj;   //  {}
myModule.updateObj({foo:'bar'});
myModule.obj;   //  still {}  :(
Run Code Online (Sandbox Code Playgroud)

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

编辑:结束了这个:

var myModule = (function(){

    var public = {
        obj: {},
        updateObj: function(newObj) {
            public.obj = newObj;
        }
    }

    return public;

}())
Run Code Online (Sandbox Code Playgroud)

T.J*_*der 5

我哪里错了?

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

不是myModule.obj对内部obj变量的引用?

没有这个:

return {
    obj: obj
    // ...
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

Ref11235只是该对象的对象引用值的plaeholder.(类似地,Ref88452是函数的对象引用,Ref71423是对函数引用的幕后"EnvironmentRecord"对象的对象updateObj引用,因此它可以更新该环境的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's值,现在指的是一个新对象.


如果您更改updateObj为更新属性:

updateObj: function(newObj) {
    this.obj = newObj;
}
Run Code Online (Sandbox Code Playgroud)

...然后你会看到你期望的结果.(在这一点上,完全取消obj变量可能是有意义的.)