javaScript函数是按值传递的。如果我们只听名字以为和值类型传递是一样的就大错特错了。
我们都知道javaScript有值传递和引用传递。值类型可以理解为把值拷贝了一份赋值给变量。一般基本类型是值传递的。
let a = 1, b = a;
console.log(b);//1
b = 3;
console.log(a);//1
console.log(b);//3
将a赋值给b,然后改变b的值,a是不影响b的。这就是按值传递。在内存中是以栈的格式储存的。
引用传递我们可以理解为传递的是指针。对象都是引用传递的。
let a = {age:20}, b = a;
console.log(b.age);//20
b.age = 30;
console.log(a.age);//30
console.log(b.age);//30
这里我们很好理解,将a赋值被b,实际是将指针赋值给了b,a和b指向的是同一对象,并没有父子级关系。用上面定义对象a为例子,定义对象我们可以理解为在内存堆中开辟一块区域为{age:20},然后将指向这个对象的指针赋值给a,然后b=a,传递的也是指针,这些变量是存在栈中的,但值是指针。所以他们都指向的是同一个对象。所以一个改变所有的都变了。
上面简单说了一下值传递和引用传递。虽然现在看起来简单,但实际工作中,会遇到类似的大坑的(哭哭哭),所以要一定要注意。接下来说函数的按值传递。这句话就看我们把这个“值”怎么去理解了。我们先看例子。
let a ={age:20};
function changeAge(obj) {
obj.age= 30
}
changeAge(a);
console.log(a.age);//30
不对啊,函数参数不是按“值”传递么,我的a为什么会变?所以函数的按值传递和基本类型的按值传递是不一样的。所以那函数的按“值”传递是什么呢?看下面这个例子
let a ={age:20},b={age :30};
function changeAge(obj) {
obj = b
}
changeAge(a);
console.log(a.age);//20
这时候我想大家也都开始明白了。这里在函数里将b赋值给a,应该是改变a的指针。但是结果a的指针并没有发生改变。所有对于对象而言,函数的按值传递的“值”,可以理解为对象的指针。不管在函数中如何操作,函数的指针都不会发生变化。这就是函数参数的按值传递。
其实我们有时候把对象的值理解为指针也能帮我们避免很多坑。引用类型的坑有时候真的多!!!