You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript对象属性复制原理:修改源对象方法为何不影响复制结果?

为什么修改原对象的方法不会影响已复制到原型的方法?

我懂你的困惑——按道理说复制引用类型的话,修改原对象应该会影响复制后的对象才对,但这里却没生效,对吧?咱们一步步拆解问题所在:

你的extend函数做了什么?

看这段核心代码:

destination[k] = source[k];

当你把circle.area赋值给RoundButton.prototype.area时,你其实是把函数对象的引用值复制了一份。这时候,circle.area和RoundButton.prototype.area就像两个独立的指针,同时指向同一个函数对象,但它们之间没有绑定关系。

打个比方:你有一个抽屉(原函数对象),circle.area是一把指向这个抽屉的钥匙,你复制了一把新钥匙给RoundButton.prototype.area。现在你把原来的抽屉换成了一个新的(重新赋值circle.area = 新函数),但新钥匙还是指向原来的旧抽屉,自然不会跟着变。

怎么实现你想要的“同步修改”效果?

如果你希望修改circle的方法后,RoundButton原型上的方法也自动更新,那你需要用原型链继承,而不是复制属性。让RoundButton.prototype的原型直接指向circle,这样当访问RoundButton.prototype.area时,会沿着原型链去circle上查找,自然会拿到最新的方法。

修改后的代码示例:

var circle = { area: function() { return Math.PI * this.radius * this.radius; } };
function RoundButton(radius) { this.radius = radius; }

// 让RoundButton的原型继承自circle
RoundButton.prototype = Object.create(circle);
// 别忘了修正构造函数的指向(否则instanceof会出问题)
RoundButton.prototype.constructor = RoundButton;

console.log(RoundButton.prototype.area); // ƒ () { return Math.PI * this.radius * this.radius;}
circle.area = function() { return Math.PI * this.radius * this.radius * this.radius; }
console.log(RoundButton.prototype.area); // ƒ () { return Math.PI * this.radius * this.radius * this.radius;}

总结一下区别

  • 属性复制:相当于给目标对象独立分配了一份属性值的引用,源对象和目标对象的属性是“各玩各的”,修改源对象的属性指向不会影响目标对象。
  • 原型链继承:目标对象的原型直接关联源对象,访问属性时会动态查找原型链,源对象的属性变化会实时反映到目标对象的属性访问中。

内容的提问来源于stack exchange,提问作者Dharmendra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:37:38