我的理解是对象通过引用传递。 我已经实现了模块模式如下。
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 {} :(
答案 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: obj
将obj
(即引用)的值复制到另一个对象的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
属性地址仍然是相同的。