Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/473.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在JavaScript中复制对象属性实际上是如何工作的?_Javascript_Object - Fatal编程技术网

在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变量的工作原理。你不是在克隆,而是在创建对对象的引用。查看javascriptis
circleFns
在其他地方定义的深度克隆?@skyboyer抱歉,我在复制和粘贴本地草稿中的代码时出错,它是
circle
对象,刚刚更正。谢谢你复制了一个函数引用。这没什么特别的,这就是js变量的工作原理。你不是在克隆,而是在创建对对象的引用。深入研究javascript中的深度克隆