js里面有一个数据类型为object(如json和数组),它创建的是一块内存区域,存放的是一个地址,所以当你直接将一个对象=另一个对象时,会发生引用。而深拷贝和浅拷贝的区别是深拷贝不会发生引用。
最最简单的浅拷贝,适用于json和数组的方法是借助JSON全局对象的parse和stringify来实现
function jsonClone(obj) {
return JSON.parse(JSON.stringify(obj));
}
var clone = jsonClone({ a:1 });
就数组而言还有一些其他的方法:
1.Array.from() 方法从一个ArrayLike或Iterable对象中创建一个新的数组实例。这是一种深拷贝的方法
备注:所谓 ArrayLike 对象指具有数组某些行为的对象,表现出来的特征就是具有 length 属性,但是这一类对象不能调用数组所具有的方法(push/forEach/map之类)。最常见的有两种:DOM中的 NodeList 和函数中的 arguments 。
在平时开发中经常遇到会遇到这样的情形,譬如将ArrayLike转化为数组从而用使用数组的方法,这时我们可以利用Array.from()
var args = Array.from(arguments);
var imgs = Array.from(document.querySelectorAll('img'));
在我之前的博客中还遇到了这样的情形,就是创建0-99的连续数组,你会发现new Array(100)在谷歌下显示的是[undefined × 100],而且此时你是不能使用数组的方法,原因很简单,这时其实只有长度,故而不能使用map等方法,当时我的解决办法是fill(1)之后再使用map,这里其实有更简单的办法
var arr = Array.from({length:100}).map((item,index) => index);
备注:这个方法的效率很低,反而for循环一个一个写效率更高
2.copyWithin()方法
这是一种浅拷贝的方法,会发生引用,看如下案例
var a=[1,2] //a为[1,2]
var b=a.copyWithin(0) //b为[1,2]
b[2]=3 //此时b为[1,2,3]
console.log(a) //a为[1,2,3]
3.slice
slice方法之前用了很多,大多知道的是创建一个新的数组,但不知道的是它其实一种浅拷贝。
对于字符串、数字及布尔值来说,slice会拷贝这些值到新的数组里。在别的数组里修改这些字符串或数字或是布尔值,将不会影响另一个数组。但如果该元素是对象,是会发生引用