【问题标题】:Passing an object by reference to a function, unexpected behaviour通过引用函数传递对象,意外行为
【发布时间】:2018-09-23 17:27:42
【问题描述】:

所以我有这段代码,我尝试通过将对象作为对函数的引用来对其进行变异:

var c = { why: 'older' };
var d;
d = c;
//passing by reference
function changeGreeting(obj) {
    obj.why = 'newer' ; // mutate         
}
changeGreeting(d)
console.log(c);
console.log(d);

这会成功变异并按预期输出: 到目前为止没有问题..

然后我的邪恶双胞胎代码看起来相同但行为不一样:

var c = { why: 'older' };
var d;
d = c;
//passing by reference, i wish..
function changeGreeting(obj) {
    obj = { why: 'newer' }; // trying to mutate..        
}
changeGreeting(d)
console.log(c);
console.log(d);

我希望它能够以相同的方式工作,但事实并非如此(它无法变异)。 寻找一个很好的明确解释为什么?

【问题讨论】:

  • 1) 与 Java 一样,JavaScript 也只有按值传递。它没有传递引用。 2)“对象”不是不能传递的值;对象始终通过引用(指向对象的指针)进行操作,并且您通过值传递引用。

标签: javascript function pass-by-reference javascript-objects


【解决方案1】:

此代码 obj = { why: 'newer' }; 不会发生变异,它只是分配给函数内部的局部变量 obj

要改变对象,你需要使用属性赋值。

换句话说,obj 指向某个对象(包含对该对象的引用),因此您可以对其进行变异。通过将值重新分配给其他对象,您正在将对原始对象的引用替换为对新对象的引用。

【讨论】:

  • 是的,现在一切都说得通了,除了“要改变对象引用,你不能使用赋值”。不是:obj.why = 'newer';通过赋值改变对象引用?它成功变异并超出了函数范围
  • @a1nb0 我修好了。马丁,如果你不同意,请回滚
  • 太棒了,这很有意义,感谢 Martin 和 Bergi
【解决方案2】:

你的函数基本上表现如下

function changeGreeting(obj) {
    var obj; // creates the local variable
    obj = d; // assign the arguments (objects are passed by reference)
    obj = { why: 'newer' }; // Creates new reference for local object        
}

由于上述行为,cd 的引用被保留,并在函数调用之前继续指向相同的内存位置。

编辑

第一个场景的行为如下所示

function changeGreeting(obj) {
    var obj; // creates the local variable
    obj = d; // assign the arguments (objects are passed by reference)
    obj.why = 'newer'; // Updates local variable obj which has same reference as "d" and "c" 
}

【讨论】:

  • 是的,这也帮助我把这个想法带回家。我仍然希望看到的是第一个示例中发生的成功变异的示例。为什么这个留在本地而第一个超出函数范围并改变对象。这方面还是有点模糊
  • @a1nb0 - 也为第一个场景添加了解释。希望它现在可以解决您的疑问。
【解决方案3】:

当你这样做时 obj = { why: 'newer' }; 您正在将函数作用域变量 obj 修改为对新对象 { why: 'newer' } 的引用。

【讨论】:

  • 是的,这就是为什么一个人留在本地并且与函数之外的那个人没有任何联系并且无法变异。有道理
猜你喜欢
  • 1970-01-01
  • 2012-02-03
  • 2017-09-11
  • 2018-09-11
  • 2020-08-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多