概述
结论是,在 J a v a S c r i p t JavaScript JavaScript中,函数参数传递都是值传递,包括 O b j e c t Object Object类型,只不过它的值是地址值。
一般类型
一般类型如 N u m b e r 、 S t r i n g 、 B o o l e a n 、 U n d e f i n e d 、 N u l l Number、String、Boolean、Undefined、Null Number、String、Boolean、Undefined、Null等,在参数传递时都是值传递,这些很好理解。我们以字符串为例:
function test(str){
str="我是字符串2";
}
s="我是字符串1";
test(s);
console.log(s);
可以看到在函数中对输入参数做修改并不会影响到实参。
对象类型
对象类型实际上也是按值传递的,但是看起来会有一点迷惑性,因为对象的存储方式和一般类型不太一样。在
j
s
js
js中,我们可以认为存储数据的区域分为栈内存和堆内存,一般类型都存储在栈内存中,对象类型存储在堆内存中,但是它的地址存储在栈内存中,这个地址就是连接二者的桥梁。
理解了这一点之后就很好说了,我们先看第一种情况:
function test(object){
object.name="李四";
console.log("在函数内: object.name = "+object.name);
}
obj={
name:"张三"
};
console.log("在函数前: obj.name = "+obj.name);
test(obj);
console.log("在函数后: obj.name = "+obj.name);
因为是按值传递,所以形参的
o
b
j
e
c
t
object
object和实参的
o
b
j
obj
obj是相等的,即对象的地址,那么通过这个地址可以修改该对象的属性。
下面来看第二种情况:
function test(object){
object=new Object()
object.name="李四";
console.log("在函数内: object.name = "+object.name);
}
obj={
name:"张三"
};
console.log("在函数前: obj.name = "+obj.name);
test(obj);
console.log("在函数后: obj.name = "+obj.name);
为什么这次没有改变呢?因为在函数第一行,我们(在堆中)新创建了一个对象并把这个对象的地址赋值给
o
b
j
e
c
t
object
object,所以它和原来所指向的对象(实参
o
b
j
obj
obj所指的对象)断开了连接,自此之后的所有操作都不会影响到原来的对象,只会影响到新的对象。综上我们可以得出一个结论,无论是基本类型还是对象类型,函数参数传递都是
b
y
v
a
l
u
e
by\ value
by value。