了解变量的传递方式

时间:2012-03-31 03:25:21

标签: javascript variables pass-by-reference pass-by-value

我只是无法理解变量是如何传递的,为什么有些是通过引用传递而另一些是按值传递的?

示例:

var a=4;
var b=a;
b=b++;
alert(a);//unmodified 4

var c=["t","ttt"];
var d=c;
d=d.sort(function(x,y){return (y.length-x.length);});
alert(c);//modified ["ttt","t"]

我在哪里可以找到哪些变量可以像第一个例子一样工作,哪个像第二个? (布尔,字符串等...有太多的东西不能通过恶误来测试它们)

4 个答案:

答案 0 :(得分:6)

JavaScript 始终按值传递。

很常见的是,JavaScript中的对象是通过引用传递的,但事实并非如此。在通过引用语言进行的真正传递中,您可以将引用传递给对象的引用,并使其指向另一个对象。这在JavaScript中是不可能的。

以C#为例。默认情况下,C#中的所有内容都按值传递,就像JavaScript一样。

void foo(string s) {
    s = "passbyvalue";
}

string a = "original value";
foo(a);
// a is still "original value"

但是,如果您更改foo以使用引用传递,则行为会更改:

void foo(ref string s) {
    s = "passbyreference";
}
string a = "original value";
foo(ref a);
// a is now "passbyreference"  

在JavaScript中,只有第一个例子是可能的。

在JavaScript中,一切都是按值传递的。这包括对象引用(是的,它令人困惑)。引用本身是一个值(它非常像指针)。它只包含一个id,允许运行时查找最有可能存储在其堆中的对象。将对象传递给函数时,实际上将其引用复制到函数

这可能是一个看似很小,甚至是肛门的差异。但这是一个关键的区别。真正通过引用传递的语言(如C#和C ++)允许您执行在JavaScript等语言中无法实现的功能。以上陈腐的例子是一个。

答案 1 :(得分:3)

想象一下JavaScript中的所有内容都是一个对象。对象引用按值复制,但对象属性仍由引用使用。所以:

var a = {};
var b = a;
b = 'Blah';
console.log(a); // Still {}

var a = {};
var b = a;
b.test = 'Blah';
console.log(a); // Is now {test: 'Blah'}

为了简化一点:属性是通过引用,值是按值。

答案 2 :(得分:1)

所有对象都按引用传递,值按值传递。 (从技术上讲,这不是真的,但它解释了行为)

答案 3 :(得分:1)

通常您可以在MDN上查看方法。例如,sort method's documentation个州(强调添加):

  

对数组的元素进行排序并返回数组。

“就地”说它会修改数组。

所有基元(例如,数字和布尔值)都按值传递;所有对象都通过引用传递,尽管有些(如String个对象)是immutable(尽管仍然通过引用传递)。