我只是无法理解变量是如何传递的,为什么有些是通过引用传递而另一些是按值传递的?
示例:
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"]
我在哪里可以找到哪些变量可以像第一个例子一样工作,哪个像第二个? (布尔,字符串等...有太多的东西不能通过恶误来测试它们)
答案 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(尽管仍然通过引用传递)。