ECMAScript中所有的函数的参数都是按值传递的。也就是说,把函数外部的值复制给函数内部的参数,就和把值从一个变量复制到另外一个变量一样。基本类型值的传递如同基本类型变量的复制一样,如下例:
let num1 = 5;
let num2 = num1;
alert(num2);//5
引用类型值的传递,如同引用类型变量的复制一样,如下例:
let obj1 = new Object();
let obj2 = obj1;
obj1.name = "nico";
alert(obj2.name);//"nico"
也就是说,obj1和obj2都指向堆内存中的同一个对象,改变obj1后obj2也会改变。
下面理解函数传递参数
在向参数传递基本类型的值时,被传递的值会复制给一个局部变量(即命名参数,或者arguments对象中的一个元素)。在向参数传递引用类型的值时,也会把这个值在内存中的地址复制给一个局部变量,因此这个局部变量的变化会反映在函数的外部。如下例:
function add(num){
num += 10;
return num;
}
let a = 20;
let result = add(a);
alert(a);//20,无变化
alert(result);//30
如果使用对象则如下:
function set(obj){
obj.name = "nico";
}
let person = new Object();
set(person);
alert(person.name);//"nico"
以上代码创建了一个person对象,然后变量被传递到set()中被复制给了obj,因为指向的同一个对象,随意当函数累不添加属性后,会被反映到全剧中。然后很多人错误的认为:在局部作用域修改的对象会在全局作用域反映出来,就说明是按引用传递的,证明如下例:
function set(obj){
obj.name = "nico";
obj = new Object();
obj.name = "ni";
}
let person = new Object();
set(person);
alert(person.name);//"nico"
在给obj复制nico后,又为obj创建了一个新对象,同时属性设置为ni。如果person是按引用传递的,那么person的属性值应该为ni的新对象,然而并不是,说明即使在函数内部修改了参数的的值,但原始的引用仍然不会变,实际上,当函数内部重写obj时,这个变量引用的就是一个局部对象了。而这个局部对象会在函数执行完毕后被立即销毁。