我们无法自行决定使用值复制还是引用复制,一切由值的类型来决定。来自 你不知道的js中篇
抛弃掉从cpp来的传值调用,引用调用,传址调用吧,js里头根本没有这些概念, 一切都由值的类型决定!
1. 传值调用:标量基本类型值。
- null
- undefined
- String
- Number
- Boolean
- symbol
let a = 1;
function func(a){//这里是传值,也就是不会有影响啦
a = a + 1;
}
func(a);
console.log(a);
2. 引用调用: 对象和函数。
let a = [1,2,3,4];
function func(a){//这里是引用调用,会同步的
a.push(5);
}
func(a);
console.log(a);
那么下面的输出是什么呢?是传值调用然后为[2,3,4,5]
吗?
let a = [1,2,3,4];
function func(a){
a = a.map((val)=> val+1)
}
func(a);
console.log(a);
为什么没变?
MDN上解释map : map() 方法创建一个新数组,其结果是该数组中的每个元素都调用一个提供的函数后返回的结果。
这其中函数的参数 a 的值的类型是数组,发生了引用调用,它先是指向传入的a,然后map创建了一个新的数组,它又指向新的数组,这期间并没有改变外界的a。
有点迷糊?过程就很像下面那个
let a = [1,2,3,4];
function func(c){
//只为形象,不代表map这么运行;
let b = [];
for(let i = 0;i < c.length; i++){
b.push(c[i]+1);
}
c = b;
}
func(a);
console.log(a);
解释: c首先指向a, b的运算过程中,并没有改变c的值,然后将c指向b;于是a数组的值没有被改变。
1. 基础值想进行引用调用怎么办?
- 把它用对象封装一下:
//let a = 1;
let obj = {
a : 1
}
function func(obj){
obj.a = obj.a + 1;
}
func(obj);
console.log(obj.a);
2. 对象想进行传值调用怎么办?
只能copy一份了
let a = [1,2,3,4];
let b = a.slice();
function func(a){
a.push(5);
}
func(b);
console.log(b);
console.log(a);
写在后面:其实上面说的就是深拷贝和浅拷贝了呢。