提问人:ajax333221 提问时间:3/31/2012 更新时间:3/31/2012 访问量:142
了解变量的传递方式
Understanding how variables are passed
问:
我只是不明白变量是如何传递的,为什么有些是通过引用传递的,而有些是通过值传递的?
例:
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"]
在哪里可以找到哪些变量像第一个示例一样工作,哪些变量像第二个示例一样工作?(布尔值、字符串等......太多了,无法自己测试它们)
答:
所有对象都按引用传递,值按值传递。(从技术上讲,这不是真的,但它解释了这种行为)
将 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'}
稍微简化一下:属性是按引用的,值是按值的。
评论
通常你可以在 MDN 上检查方法。例如,排序
方法的文档状态(强调后加):
对数组的元素进行排序并返回该数组。
那里的“就位”表示它将修改数组。
所有基元(例如,数字和布尔值)都按值传递;所有对象都是通过引用传递的,尽管有些对象(如对象)是不可变的(尽管仍然通过引用传递)。String
评论
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,允许运行时查找最有可能存储在其堆中的对象。当您将对象传递给函数时,您实际上是在将其引用复制到函数中
这可能是一个看似很小的,甚至是肛门的差异。但这是一个关键的区别。具有 true 传递引用的语言(如 C# 和 C++)允许您执行在 JavaScript 等语言中根本无法完成的事情。上面这个陈词滥调的例子就是其中之一。
评论