Javascript赋值操作是复制引用?

时间:2012-01-09 17:18:33

标签: javascript reference variable-assignment

基本示例:

var b = 10;
var c = b;
b++;
console.log(b,c);

>> 11 10

c看起来像是b的副本。

但在另一个案例中:

var x = {};
var y = x;
x.abc = 10;
console.log(x.abc, y.abc);

>> 10 10

为什么y不是x的副本,而是指向同一个实例x指向的引用?

此外,我猜测b++会创建另一个实例,因此b指向新实例,但c指向旧实例。然而...

var u = 10;
setTimeout(function() {
  console.log(u);
}, 10000)
u++;

>> 11

如果u++创建了一个新实例,那么匿名函数中的u应该指向旧的u,不应该吗?

4 个答案:

答案 0 :(得分:10)

  

c看起来像b的副本。

两者都引用相同的不可变值。

  

为什么y不是x的副本,而是指向实例x指向的引用?

x首先是对象的引用,因此y是它的副本(引用的副本,而不是对象的副本)。

  

如果u++创建了新实例,

没有。

  

匿名函数中的u应该指向旧的u,不应该吗?

u++将对11的引用分配给u。匿名函数在创建函数时查看u而不是“u的值”。

答案 1 :(得分:9)

分配基元时,会按按值分配基元;引用类型(如您的对象)通过引用分配 (或者,当Jon Skeet对我进行更正时,会为它们分配引用的副本)。

在你的第二个例子x和y中,指向内存中的同一个对象。这就是为什么将abc属性添加到其中的原因,也将其添加到其他

您还会观察到将x或y传递给函数

的相同行为
function addABC(foo) {
   foo.abc = 10;
}

var x = {};
var y = x;
addABC(x);
console.log(x.abc, y.abc);

请注意,虽然x和y指向内存中的同一个对象,但它们是引用的单独副本,所以这个

    var x = { a: 1 };
    var y = x;
    y = {};
    alert(x.a);

和这个

    var x = { a: 1 };
    var y = x;
    x = {};
    alert(y.a);

仍会提示1。

答案 2 :(得分:4)

本声明:

var y = x;

x的值复制为y的初始值。但是,涉及的值是对象的引用,而不是对象本身。请注意,这与相同,即分配复制“对x的引用” - 它实际上是x。因此,特别是,如果您更改x的值以引用其他对象,例如

x = "something else";

然后不会改变y的值 - 它的值仍然是对原始对象的引用。

答案 3 :(得分:0)

  • 分配给变量的typeof值决定该值是按按值分配还是按引用分配存储

  • 在变量分配中,标量原始值(Number,String,Boolean,undefined,null,Symbol)按值分配,而复合值(Object,Array)按引用分配

如果有疑问,请通过示例进行解释 链接: how references work