js的浅拷贝和深拷贝

发布时间:2019-08-19 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了js的浅拷贝和深拷贝脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。
@H_304_0@

经常遇到数组或对象等引用类型作为函数的参数的情况,但又不想修改原来的数据,这时候就需要拷贝(基本类型的变量不需要考虑)。
拷贝分为浅拷贝深拷贝。浅拷贝是引用复制,深拷贝是完全单纯拷贝数据的值。因为数组是最常见的引用类型,所以下面大部分拿数组举例。

    @H_360_9@

    浅拷贝

VAR a = [1,2,3]
var b = a
console.LOG(b) //Array(3) [1, 2, 3]
b[1] = 0
console.log(b) //Array(3) [1, 0, 3]
console.log(a) //Array(3) [1, 0, 3]

可以看出,修改数组b的时候,数组a也被修改了。这显然不是想要的做法。

要想不改变原来的数组,就要用到以下的几种方法:

var a = [1,2,3]
var b = a.concat() //或 var b = [].concat(a)
console.log(b) //Array(3) [1, 2, 3]
b[1] = 0
console.log(b) //Array(3) [1, 0, 3]
console.log(a) //Array(3) [1, 2, 3]
var a = [1,2,3,4,5]
var b = a.slice(0)
console.log(b) //Array(5) [1, 2, 3, 4, 5]
b[0] = 0
console.log(a) //Array(5) [1, 2, 3, 4, 5]
console.log(b) //Array(5) [0, 2, 3, 4, 5]

还可以部分拷贝

var a = [1,2,3,4,5]
var b = a.slice(1, 3) //返回[1,3)下标区间的数
console.log(b) //Array(2) [2, 3]
//负数也可以
console.log(a.slice(-2)) //Array(2) [4, 5]

还有一种方法,跟循环的方法有点类似,就是es6的新特性,展开语法

var a = [1,2,3,4,5]
var b = [...a]
b[0] = 0
console.log(a) //Array(5) [1, 2, 3, 4, 5]

这个方法就是逐一枚举a中的值,放到空数组中

但是,以上这几种拷贝方法看似都不会改变原来数组,其实也还是属于浅拷贝范畴。如果原数组里面还有引用类型数组,这些方法都会失效(比如二维数组)

var a = [[1,2,3],[4,5,6]]
var b = a.slice(0)
b[0][4] = 0
console.log(a[0]) //[[1, 2, 0],[4,5,6]]

其他concat,[...]等方法也一样。
可以这么理解:原数组就像一个带锁的独一无二的箱子,里面有各种零食。简单的引用复制,其实就是配了一把钥匙,谁动过里面的东西,其他人都会受到影响。而上面这4种方法其实就是自己买一个不同箱子,参照原来的箱子里面的零食,去某宝买同款。动自己箱子的东西,原来的箱子不受影响。但是如果原来的箱子里面还套了个独一无二带锁的箱子,某宝买不到同款,那没办法,里面的箱子只能还是配把钥匙共用。所以,这4种方法只是简单绕过第一层箱子的引用复制


  • 深拷贝

目前比较好的方法就是json大法JSON.stringify(),要么就是自己写递归的深拷贝函数。
JSON.stringify()是将对象或数组序列化成字符串。然后再用JSON.parse()解析成值或对象。

var a = {aa:1,bb:[1,2],cc:[3,4]}
var b = JSON.parse(JSON.stringify(a))
console.log(b) //{aa:1,bb:[1,2],cc:[3,4]}
b.cc[0] = 0
console.log(a) //{aa:1,bb:[1,2],cc:[3,4]}
console.log(b) //{aa:1,bb:[1,2],cc:[0,4]}

附带深拷贝的自定义函数(自大佬mqyqingfeng的gIThub

var deepCopy = function(obj) {
    if (tyPEof obj !== 'object') return;
    var newObj = obj instanceof Array ? [] : {};
    for (var key in obj) {
        if (obj.hasOwnPRoperty(key)) {
            newObj[key] = typeof obj[key] === 'object' ? deepCopy(obj[key]) : obj[key];
        }
    }
    return newObj;
}

脚本宝典总结

以上是脚本宝典为你收集整理的js的浅拷贝和深拷贝全部内容,希望文章能够帮你解决js的浅拷贝和深拷贝所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。