【问题标题】:When are objects copied rather than passed as a reference'何时复制对象而不是作为引用传递'
【发布时间】:2013-10-05 13:14:45
【问题描述】:

如果对象是通过引用传递的,而函数是对象,那么有人可以解释一下这种行为:

function extendCopy(p){
  var c = {}
  for (var i in p){
     c[i] = p[i];
  }
  c.uber = p;
  return c;
}
var shape = {
   name: "shape";
   toString: function (){ return name; }
}
var twoDee = extendCopy(shape);
twoDee.toString = function() { return "2d shape" }

>>>shape.toString
>>>function (){ return name; }

为什么twoDee.toString 不仅仅是对shape.toString 的引用?复制函数中的c[i] = p[i]; 行肯定会将新对象的属性设置为对复制对象中相同属性的引用吗?

编辑

这可以简化:

如果函数是对象并且对象通过引用传递,为什么返回"test" 而不是"modified"?是不是因为我实际上是在用第 3 行的新对象完全替换“对象”(函数)?

a.toString = function(){ return "test" };
b.toString = a.toString;
a.toString = function(){ return "modified" };
b.toString();
>>> "test"

【问题讨论】:

  • 这个例子是错误的; john 被回显。改为显示真实代码。
  • 哦,你是对的,让我调整一下问题
  • 如果控制台使用缓存,您偶尔会在控制台中看到错误结果
  • Javascript 总是按值传递参数(对于一个对象,该值是一个引用),但无论如何这不适用于您拥有的代码,因为您根本没有传递任何参数。
  • 我试图过度简化问题,我已经发布了让我感到困惑的代码

标签: javascript pass-by-reference


【解决方案1】:

复制作为对象引用的属性值只会复制引用。它不会导致值的接收者成为对其他属性的引用。

例子:

var a = { x: { name: 'John' } };
var b = {};

b.x = a.x; // b.x points to the same object as a.x;

a.x = { name: 'Peter' }; // a.x points to a different object, b.x is unchanged

当您将值从a.x 复制到b.x 时,b.x 的值是对a.x 指向的同一对象的引用,它不是对a.x 本身的引用。

函数引用也是如此。当您复制函数的引用时,您只复制引用值。如果原始值被差异引用替换,则不会更改从中复制的值。

【讨论】:

  • 谢谢,我发现这个问题真的很难用语言表达(因此有人反对!)但你已经完美地表达了你的答案。现在这很有意义!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-06
  • 1970-01-01
  • 2016-05-17
  • 2012-07-08
  • 1970-01-01
相关资源
最近更新 更多