javascript模块模式返回对象引用

javascript module pattern return object reference?

本文关键字:对象引用 返回 模式 模块 javascript      更新时间:2023-09-26

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

var myModule = (function(){
    var obj = {};
    return {
        obj: obj,
        updateObj: function(newObj) {
            obj = newObj;
        }
    }
}())
myModule.obj;   //  {}
myModule.updateObj({foo:'bar'});
myModule.obj;   //  still {}  :(

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

编辑:最后用这个:

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

我哪里错了?

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

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

没有。此:

return {
    obj: obj
    // ...
}

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

在创建了myModule之后,在调用updateObj之前,以下是内存中的内容(省略了一些无关的细节):

++|++|+−>|执行上下文||+||obj:Ref11235|−−−−+|+----+|||++|+对象|||变量"myModule"||+-+-+-+-+|+----+|||目标:参考文献11235|+-+-+-+-||updateObj:Ref88452|−−−−->|函数||+||环境:参考71423 |−−+|[[代码]|++

Ref11235只是该对象引用值的占位符。(类似地,Ref88452是函数的对象引用,Ref71423是updateObj函数引用的幕后"EnvironmentRecord"对象的对象参考,因此它可以更新该环境的obj变量。)

调用updateObj后,您已经更改了myModuleobj属性中的引用,但这不会更改obj变量中的引用:

++|++||+−−−−对象||+−>|执行上下文||+|+----+|||目标:参考文献11235 ||+对象||+−−>>|+----+| foo:"bar"|||变量"myModule"||+|+----+|||目标:参考文献65243|+-+-+-+-||updateObj:Ref88452|−−−−->|函数||+||环境:参考71123 |−−+|[[代码]|++

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


如果更改updateObj以更新属性,则改为:

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

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

问题是updateObj中的obj没有引用模块中定义的obj变量。要引用与myModule中相同的obj,请使用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);

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

不,不是。

CCD_ 23创建一个对象并为其指定一个引用作为CCD_ 24的值。

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

CCD_ 28用对新对象的引用覆盖CCD_ 29的值。这不涉及obj属性,因此它仍然是对第一个对象的引用。

这个类似于下面的代码:

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

这不起作用,因为在a={some:1}行中,您将丢失与b的链接。
希望这会有意义!

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