了解通过引用传递vs使用函数的值

时间:2014-05-12 12:33:16

标签: javascript

据我所知,对象在JavaScript中通过引用传递(原语通过值传递?)。

var a, b;
a = {
    Foo: "Bar"
}
b = a;
a.Foo = "Other";
console.log(b.Foo); // "Other"

这与数组的工作方式类似,但不像我期望的那样有效:

var a, b;
a = function(){ return 20; }
b = a;
a = function(){ return 40; }
console.log(b()); // returns 20 ?
我很困惑,因为我认为功能是对象。上面的例子不应该返回40吗?

4 个答案:

答案 0 :(得分:11)

在第一种情况下,a.Foo = ...,您正在更改对象中属性的值,由ab引用。这称为变异对象。

但在第二种情况下,您正在使a引用一个新的函数对象。现在,ab指的是不同的函数对象。

这就是为什么你在第二种情况下得到20

答案 1 :(得分:2)

@thefoutheye's answer之后,请考虑以下语句证明函数是对象

var a, b;
a = function() { return 20; }
a.Foo = "Bar";
b = a;
a.Foo = "Other";
console.log(b.Foo); // "Other"

答案 2 :(得分:2)

首先关于标题中的问题(实际上与您使用代码示例演示的内容不同):

  

"据我所知,对象在JavaScript"

中通过引用传递

不,Javascript根本不支持通过引用传递参数。所有参数都按值传递,但该值可以作为参考。

示例:

var a = { answer: 42 };

function f(x) {
  alert(x.answer); // shows 42
  x = { answer: 0 };
  alert(x.answer); // shows 0
}

f(a);
alert(a.answer); // shows 42

当参数按值传递时,变量x与变量a分开,因此将新对象分配给x并不会更改{的值{1}}。

返回您的代码:

将变量的对象引用分配给另一个时,它是复制的引用,而不是对象。你得到两个引用同一个对象的变量。

任何一个变量都可用于访问对象中的成员,这是您的第一个代码示例演示的内容。

如果将新对象分配给第一个变量,则将替换变量中的引用,不会覆盖当前指向的对象。对象仍然完好无损,第二个变量仍然指向它。您将获得两个指向每个对象的变量,这是您的第二个代码示例所演示的。

答案 3 :(得分:1)

您正在将变量a重新分配给新函数。这与更改房产价值不同。

尝试:

var a, b;
a = {Foo: function() {return 20;}};
b = a;
a.Foo = function() {return 40;};
console.log(b()); // returns 40