我们无法自行决定使用值复制还是引用复制,一切由值的类型来决定。来自 你不知道的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);

写在后面:其实上面说的就是深拷贝和浅拷贝了呢。