JavaScript:通过引用传递对象

4

在我的应用程序中,当我将数据传递给不同的对象时,我不确定是否会出现数据重复。只是举个例子,请看以下代码:

var DataStore = function(data) {
    this.data = data; // <-- typeof data === 'object'
}

var Controller = function() {
    var dataStore = new DataStore({foo: 'bar'});
    var plugin = new Plugin(dataStore.data);
}

var Plugin = function(data) {
   this.data = data;
}

var app = new Controller();

当我创建插件时,数据属性从dataStore传递进来。然后被分配给Plugin内部的一个属性。请记住,传递的数据是一个对象,我的问题是,这样做是在内存中创建了两个变量,还是Plugin中的数据属性引用DataStore对象中的属性?
如果赋值后它不保留引用,我如何将DataStore传递到插件中并在本地保留引用?或者我需要将DataStore作为全局变量保存在应用程序范围内,并从插件中全局引用它吗?

据我所知,JavaScript对象始终是引用。 - Alvin Wong
3
@AlvinWong 不完全正确。在 ECMAScript 实现(例如 JavaScript)中,只能通过引用访问对象,并且对象引用是 (可以被赋值)。与其他编程语言中所知的按引用调用不同,它 不存在,它总是按值调用。这与 Java 等语言相同。 - PointedEars
2个回答

11

dataStore.dataplugin.data都指向同一个对象 - 在任何一个“类”(缺乏更好的术语)中对该对象进行改变都会导致另一个也被改变(因为它们都持有指向同一对象的引用)。


2
这是正确的,也许是未来谷歌搜索者想要的实用信息。虽然这里的其他答案/评论列出了JavaScript实际上不是“按引用调用”的技术原因,但从程序员的角度来看,它仍然表现得非常相似,特别是在处理对象参数时。此外,我还要补充的是,如果您不希望出现这种行为,您需要执行类似以下操作(使用jQuery,但每个库都有自己的实现)var copy = $.extend(true, {}, data); 然后传递 copy 而不是 data - Kevin Jhangiani

0

在JS中,函数参数始终是按引用传递的。当您将对象作为参数传递时,实际传递的是指向对象在内存中位置的指针。如果您尝试覆盖引用本身,则原始对象不会受到任何影响,但是如果更改对象的任何属性的值,则原始对象将被修改。

例如:

function f1(_x) {
    _x = 5;
}

function f2(_y) {
    _y.name = 'Hello';
}

var x = 10;
f1(x);
console.log(x); // no change to x

var y = {name: 'Tom'};
f2(y);
console.log(y.name); // y.name is now Hello

不,JS 中没有“按引用传递”的概念,函数参数和其他值没有区别。在语言层面上不存在指针(可能在实现层面上有,但未指定)。引用并没有被覆盖,参数值被覆盖了,而且参数是函数内部的局部变量。 - PointedEars
1
@SeainMalkin 你接受了一个错误的答案。你明白只有引用值被复制(按值调用),而不是对象吗? - PointedEars
3
“按引用传递”或者你所说的“引用传递”在编程中有一个特定的意义。在JS中说“函数参数是按引用传递”的话是完全错误的,因为它们并没有什么特殊的地方。被赋值和被传递的是一个引用值,作为这样被传递到函数里面(按值传递)。请参阅MDN上的“函数和函数作用域”(Functions and function scope)。 - PointedEars
1
@techfoobar 更正:SpiderMonkey 是用 C 写的。 - PointedEars
1
@PointedEars的术语可能不是很完美,但它表达了要点,并且示例证明了我想知道的东西。 - Seain Malkin
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接