JavaScript中引用vs复制示例详析
前言
好像一般很少人讲到js中的引用和复制,不过弄清楚这个概念可以帮助理解很多东西
先讲一下很基础的东西,看看js中几种数据类型分别传的什么
引用:对象、数组、函数
复制:数字、布尔
字符串单独说明,因为它的特殊性,无法确定是传递引用还是复制数值(因为字符串的值是没法改变的,所以纠结这个问题也是没意义的)但是用于比较的时候显然是属于传值比较
下面来一起看看详细的介绍吧
首先我们看下面这个例子:
letage=18; letage2=age; console.log(age,age2);
我们会得到以下的值:
1818
这个相信大家都能很好理解。
那么如果我们改变age的值呢?输出会有什么变化?
age=20; console.log(age,age2);
我们会得到:
2018
看到这里大家就奇怪了,上面的结果都很正常啊。
但在JavaScript中是有例外的,对于普通数据类型如integer,string,boolean可以通过=来复制这个变量,但对于array和object数据类型,=只能起到引用的效果。
大家可以看下面这个例子:
letarr=['wes','bob','faker']; letarr2=arr; console.log(arr2,arr); arr[2]='dean'; console.log(arr2,arr);
得到的结果是:
["wes","bob","faker"]["wes","bob","faker"]
["wes","bob","dean"]["wes","bob","dean"]
我们会发现随着arr的改变,arr2也会跟着改变。
说明arr2并没有复制arr的值,只是引用了它,它们都指向同一个内存中的值。
object也是一样的:
letobj={ age:19, name:'like', last:'jam' }; letobj2=obj; console.log(obj,obj2); obj.age=50; console.log(obj,obj2);
得到的结果是:
{age:19,name:"like",last:"jam"}{age:19,name:"like",last:"jam"}
{age:50,name:"like",last:"jam"}{age:50,name:"like",last:"jam"}
那么如何复制array和object呢?
复制array的方法:
方法1:
letarr2=[].concat(arr);
方法2:
letarr2=arr.slice();
方法3:
letarr2=Array.from(arr);
方法4:
letarr2=[...arr];
一般我们比较常用的是方法3和方法4,方法1和方法2比较取巧,但都是可以达到复制array的目的的。
ps:[...arr]是ES6中的方法。
复制object的方法:
方法1:
letobj2=Object.assign({},obj);
方法2:
letobj2={...obj};
方法1和方法2都有个缺点,它们只会复制对象的第一层。
看下面这个例子:
letobj={ number:12, name:{ first:'bob', last:'evil' } }; letobj2=Object.assign({},obj); obj.number=50; console.log(obj,obj2);
我们会得到下面的结果:
obj={
number:50,
name:{
first:'bob',
last:'evil'
}
}obj2={
number:12,
name:{
first:'bob',
last:'evil'
}
}
但如果我们改变第二层的值:
obj.name.first='sam'; console.log(obj,obj2);
obj={
number:50,
name:{
first:'sam',
last:'evil'
}
}obj2={
number:12,
name:{
first:'sam',
last:'evil'
}
}
我们发现对象第二层依旧是引用的,并没有实现复制。
那么怎么复制一个完整的object呢?
最简单的方法就是使用第三方函数库lodash,它提供了clone和deepclone完全可以满足日常的需求。
object的复制因为要考虑到很多因素,我会另开一篇,专门整理。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对毛票票的支持。