标签:
我们把命名参数(arguments)视为局部变量,在向参数传递基本类型值时,如同基本类型变量的复制一样,传递一个副本,参数在函数内部的改变不会影响外部的基本类型值。如:
1 function add10(num){ 2 num += 10 ; 3 return num ; 4 } 5 var count = 10 ; 6 var result = add10(count); 7 alert(count);// 10 8 alert(result); //20
在向参数传递引用类型的值时,会把这个值 在内存中的地址复制给一个局部变量,因此这个局部变量的变化会反映子啊函数的外部,例如:
function addName(obj){
obj.name = "Jewl";
}
var someBody = new object();
addName(someBody);
console.log(someBody.name); //"Jewl"
这个例子其实是很让人困扰的,因为它更像按引用传递,说到传递方式,一般分为两种:
1.按值传递(call by value):函数的形参是被调用时所传实参的副本。修改形参的值并不会影响实参。
2.按引用传递(call by reference):函数的形参接收实参的隐式引用,而不再是副本。这意味着函数形参的值如果被修改,实参也会被修改。同时两者指向相同的值。
为了证明引用类型也是按值传递的,我们可以看看下面一个例子:
function addName(obj){
obj.name = "Jewl‘;
obj = new object();
obj.name = "Kancy";
}
var someBody = new object();
addName(someBody);
console.log(someBody.name) //"Jewl"
与前面一个例子的区别是,本例将一个新对象赋值给形参,如果是按引用传递,那么someBody的name也会随之改变,显然不是。在函数内部给obj赋值时,这个变量引用就变成了一个局部变量,在函数执行完就会被销毁。
为了加深理解,我会再来看看js中引用类型值的存储,在js中,引用类型值是保存在内存中的对象,JavaScript不允许直接访问内存中的位置,也即不能直接操作对象的内存空间,在操作对象时,实际上是操作对象的引用而不是实际的对象。引用类型的值是按引用访问的。因此改变其中一个变量,就会影响另外一个变量。
var obj1 = new Object();
var obj3 = new Object();
var obj2 = obj1;
obj1.name = "Jewl";
obj3.name = "Kancy";
console.log(obj1.name); //"Jewl"
console.log(obj2.name); //"Jewl"
obj1 = obj3;
console.log(obj1.name); //"Kancy"
console.log(obj2.name); //"jewl"
console.log(obj3.name); //"kancy"
当我们把obj1赋值为obj3时,obj1指向和obj3相同的对象,obj2依然指向之前的对象。由此可以看出传参过程和此处类似,但不属于按引用传参,(前面讲过原因),所以讲JavaScript里参数传递均归为按值传递。
学习笔记:JavaScript传参方式———ECMAScript中所有函数的参数都是按值传递
标签:
原文地址:http://www.cnblogs.com/Jewl/p/5440791.html