本文地址:kamal
JavaScript 中所有函数的参数都是按值传递的
当参数是值类型的时候
function changeStuff(num){ num = num * 10; } var num = 10; changeStuff(num); alert(num);//10
可以看到当函数参数是值类型的时候在函数内部改变变量的值,不会在函数作用域外表现出来,说明函数参数是传值的方式传入函数内部。
当函数参数是Object类型的时候
function changeStuff1(obj1){ obj1.item = "changed"; } var obj1 = new Object(); obj1.item = "unchanged"; changeStuff1(obj1); alert(obj1.item); //changed
这时obj1内的item的值在函数之外表现出来了,如果是传值的话,函数内部改变变量的值应该不会影响到外部的obj1啊。难道对Object类型的参数传的是传引用? 再看第三个例子
function changeStuff2(obj2){ obj2 = {item:"changed"}; } var obj2 = new Object(); obj2.item = "unchanged"; changeStuff2(obj2); alert(obj2.item);//unchanged
《JavaScript高级程序设计》一书中就解释到这里就说已经证明了“ECMAScript 中所有函数的参数都是按值传递的”。可是我还是不能理解为什么第二个和第三个例子会有不一样的结果。又找了一些函数传参数的解释[1]
传值 是把实参的值赋值给行参 那么对行参的修改,不会影响实参的值 传地址 是传值的一种特殊方式,只是他传递的是地址,不是普通的如int 那么传地址以后,实参和行参都指向同一个对象 传引用 真正的以地址的方式传递参数 传递以后,行参和实参都是同一个对象,只是他们名字不同而已 对行参的修改将影响实参的值
在第二个例子中,obj1传入函数 changeStuff1 时,changeStuff1函数内部变量 obj1是一个新的内存变量,只是期指向旧的对象值,所以改变对象中item的值会在函数外部表现出来。
在第三个例子中obj2传入函数 changeStuff12时,changeStuff2函数内部变量 obj2是一个新的内存变量,依旧期指向旧的对象值,但在函数内部又给内部的obj2变量重新赋值,使其指向一个新的对象,所以改变对象中item的值不会影响函数外部的obj2对象。
最后得出结论,JavaScript 中所有函数的参数都是按值传递的 ,只是对于Object类型来说,这个值本身就是一个指向Object对象的地址。最后给出完整的测试函数[2]
function changeStuff(num, obj1, obj2) { num = num * 10; obj1.item = "changed"; obj2 = {item: "changed"}; } var num = 10; var obj1 = new Object(); obj1.item = "unchanged"; var obj2 = new Object(); obj2.item = "unchanged"; changeStuff(num, obj1, obj2); alert(num); //10 alert(obj1.item); //changed alert(obj2.item); //unchanged
[2] Is JavaScript is a pass-by-reference or pass-by-value language?
//20141205 append
几个例子用相同的变量名,有误导之嫌,起码函数参数可以用别的名称