按值传递中函数的形参是被调用时所传实参的副本。修改形参的值并不会影响实参。而按引用传递(pass-by-reference)
时,函数的形参接收实参的隐式引用,而不再是副本。这意味着函数形参的值如果被修改,实参也会被修改。同时两者指向相
同的值。我们首先看下 C 中按值传递与引用传递的区别:
void Modify(int p, int * q)
{
p = 27; // 按值传递 - p是实参a的副本, 只有p被修改
*q = 27; // q是b的引用,q和b都被修改
}
int main()
{
int a = 1;
int b = 1;
Modify(a, &b); // a 按值传递, b 按引用传递,
// a 未变化, b 改变了
return(0);
}
而在 JavaScript 中,对比例子如下:
function changeStuff(a, b, c)
{
a = a * 10;
b.item = "changed";
c = {item: "changed"};
}
var num = 10;
var obj1 = {item: "unchanged"};
var obj2 = {item: "unchanged"};
changeStuff(num, obj1, obj2);
console.log(num);
console.log(obj1.item);
console.log(obj2.item);
// 输出结果
10
changed
unchanged
JavaScript 按值传递就表现于在内部修改了 c 的值但是并不会影响到外部的 obj2 变量。如果我们更深入地来理解这个问
题,JavaScript 对于对象的传递则是按共享传递的(pass-by-sharing,也叫按对象传递、按对象共享传递)。最早由Barbara
Liskov. 在1974年的GLU语言中提出;该求值策略被用于Python、Java、Ruby、JS等多种语言。该策略的重点是:调用函数
传参时,函数接受对象实参引用的副本(既不是按值传递的对象副本,也不是按引用传递的隐式引用)。 它和按引用传递的不同
在于:在共享传递中对函数形参的赋值,不会影响实参的值。按共享传递的直接表现就是上述代码中的 obj1,当我们在函数
内修改了 b 指向的对象的属性值时,我们使用 obj1 来访问相同的变量时同样会得到变化后的值。
连续赋值
JavaScript 中是支持变量的连续赋值,即譬如:
var a=b=1;
但是在连续赋值中,会发生引用保留,可以考虑如下情景:
var a = {n:1};
a.x = a = {n:2};
alert(a.x); // --> undefined
为了解释上述问题,我们引入一个新的变量: