在JavaScript中复制对象属性实际上是如何工作的?
让我们以圆形对象为例。当我使用自定义的在JavaScript中复制对象属性实际上是如何工作的?,javascript,object,Javascript,Object,让我们以圆形对象为例。当我使用自定义的extend函数将此对象的属性复制到RoundButton时,我认为RoundButton将从circle对象获取area方法的引用 因此,如果我在circle中更改area方法的定义,它也会在RoundButton中更改area属性,但在控制台中,它仍然保持原来的状态。我真的很困惑,如果我没有克隆属性,而是复制了它们,为什么会这样 var circle = { area: function() { return
extend
函数将此对象的属性复制到RoundButton
时,我认为RoundButton
将从circle
对象获取area
方法的引用
因此,如果我在circle
中更改area
方法的定义,它也会在RoundButton
中更改area
属性,但在控制台中,它仍然保持原来的状态。我真的很困惑,如果我没有克隆属性,而是复制了它们,为什么会这样
var circle = {
area: function() {
return Math.PI * this.radius * this.radius;
}
};
function extend(destination, source) {
for( var k in source ){
if(source.hasOwnProperty(k)) {
destination[k] = source[k];
}
}
return destination;
}
var RoundButton = function (radius) {
this.radius = radius;
};
extend(RoundButton.prototype, circle);
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;}
重新分配时:
circle.area = function() {
return Math.PI * this.radius * this.radius * this.radius;
}
…上一个区域
函数对象丢失一个引用。仍然引用circle.area
的任何对象都将保留相同的引用,但circle
本身现在将有一个不同的新函数引用
这是赋值的结果,也是JavaScript中的标准行为
在您的示例中,您可以通过不将circle
的属性复制到RoundButton.prototype
对象(使用extend
)而将circle
分配给该prototype
,来获得所需的行为。这样,圆
对象的突变将直接影响原型
(因为它们是相同的对象引用)。因此,请替换:
extend(RoundButton.prototype, circle);
与:
它会像你期望的那样工作
同样,在原始版本中,RoundButton.prototype
不会直接引用circle
对象,而是直接引用其成员值(也就是面积函数)。通过将值指定给圆对象自身的属性,圆对象的任何变化都不会引起原型对象的注意。重新指定时:
circle.area = function() {
return Math.PI * this.radius * this.radius * this.radius;
}
…上一个区域
函数对象丢失一个引用。仍然引用circle.area
的任何对象都将保留相同的引用,但circle
本身现在将有一个不同的新函数引用
这是赋值的结果,也是JavaScript中的标准行为
在您的示例中,您可以通过不将circle
的属性复制到RoundButton.prototype
对象(使用extend
)而将circle
分配给该prototype
,来获得所需的行为。这样,圆
对象的突变将直接影响原型
(因为它们是相同的对象引用)。因此,请替换:
extend(RoundButton.prototype, circle);
与:
它会像你期望的那样工作
同样,在原始版本中,RoundButton.prototype
不会直接引用circle
对象,而是直接引用其成员值(也就是面积函数)。圆
对象通过将值分配给其自身属性而发生的任何变化都不会被该原型对象注意到。在javascript中,对象(函数是对象)通过引用分配给变量,而不像原始值字符串
、数字
或布尔值
假设分配给circle.area
的函数用“X”表示
稍后,将此函数指定给差分变量
var RoundButton = {
area: circle.area // "X"
};
所以RoundButton.area
也指的是我们的“X”。现在如果你这样做了:
circle.area = new Function("return 1");
您将更改圆圈的引用。area,但是,RoundButton。area
仍然引用该“X”。在javascript中,对象(函数是对象)通过引用分配给变量,这与基本值string
、number
或boolean
不同
假设分配给circle.area
的函数用“X”表示
稍后,将此函数指定给差分变量
var RoundButton = {
area: circle.area // "X"
};
所以RoundButton.area
也指的是我们的“X”。现在如果你这样做了:
circle.area = new Function("return 1");
您将更改
圆圈的引用。area
,但RoundButton.area
仍然引用该“X”。是圆圈
在其他地方定义的吗?@skyboyer抱歉,我在复制和粘贴本地草稿中的代码时出错,它是圆圈
对象,刚刚更正。谢谢你复制了一个函数引用。这没什么特别的,这就是js变量的工作原理。你不是在克隆,而是在创建对对象的引用。查看javascriptiscircleFns
在其他地方定义的深度克隆?@skyboyer抱歉,我在复制和粘贴本地草稿中的代码时出错,它是circle
对象,刚刚更正。谢谢你复制了一个函数引用。这没什么特别的,这就是js变量的工作原理。你不是在克隆,而是在创建对对象的引用。深入研究javascript中的深度克隆