实现深浅拷贝

1.数组拷贝

1.浅拷贝(新数组改变还会对原数组影响)

Array.slice()与Array.concat()

var source = [1, null, undefined, {name: 'anjou', age: undefined, sex: null}, [2, 3, 4], function() {}]
    var target = source.slice() || source.concat()
    target[0] = 5
    target[3].name = '====';
    target[4][0] = 6
    console.log(source)  // [1, null, undefined, {name: '====', age: undefined, sex: null}, [6, 3, 4], ƒ ()]
    console.log(target)  // [5, null, undefined, {name: '====', age: undefined, sex: null}, [6, 3, 4], ƒ ()]

es6 扩展运算符

var source = [1, null, undefined, {name: 'anjou', age: undefined, sex: null}, [2, 3, 4], function() {}]
    var target = [...source]
    target[0] = 5
    target[3].name = 'anpoly';
    target[4][0] = 6
    console.log(source)  // [1, null, undefined, {name: 'anpoly', age: undefined, sex: null}, [6, 3, 4], ƒ ()]
    console.log(target)  // [5, null, undefined, {name: 'anpoly', age: undefined, sex: null}, [6, 3, 4], ƒ ()]

es6 Object.assign()

var source = [1, null, undefined, {name: 'anjou', age: undefined, sex: null}, [2, 3, 4], function() {}]
    var proto = Object.getPrototypeOf(source)
    var target = Object.assign({}, Object.create(proto), source)
    target[0] = 5
    target[3].name = 'anpoly'
    target[4][0] = 6
    console.log(source)  // [1, null, undefined, {name: 'anpoly', age: undefined, sex: null}, [6, 3, 4], ƒ ()]
    console.log(target)  // [5, null, undefined, {name: 'anpoly', age: undefined, sex: null}, [6, 3, 4], ƒ ()]

2.深拷贝(彻底切断了数组内引用类型的引用关系)
JSON.parse()与 JSON.stringify()

 var source = [1, null, undefined, {name: 'anjou', age: undefined, sex: null}, [2, 3, 4], function() {}]
    var target = JSON.parse(JSON.stringify(source))
    target['0'] = 5
    target['3'].name = 'anpoly'
    target['4'][0] = 8
    console.log(source)  // [1, null, undefined, {name: 'anjou', age: undefined, sex: null}, [2, 3, 4], ƒ ()]
    console.log(target)  // [5, null, null, {name: 'anpoly', sex: null}, [6, 3, 4], null]

我们发现使用JSON.parse与JSON.stringify可以实现数组的深拷贝。但是我们发现拷贝后的数组与我们预想的结果有很大差别,这是因为JSON.stringify(…) 在对象中遇到 undefined 、 function 和 symbol 时会自动将其忽略, 在 数组中则会返回 null (以保证单元位置不变)

2.对象拷贝

1.浅拷贝
es6 Object.assign()

var source2 = {0:1, 1:null, 2:undefined, 3:{name: 'anjou', age: undefined, sex: null}, 4:[2, 3, 4], 5: function() {}}
var obj = Object.getPrototypeOf(source2)
var target = Object.assign({}, Object.create(obj), source2)
target['0'] = 5
target['3'].name = 'anpoly'
target['4'][0] = 6
console.log(source2)  // {0: 1, 1: null, 2: undefined, 3: {name: "anpoly", age: undefined, sex: null}, 4: [6, 3, 4], 5:ƒ ()}
console.log(target)   // {0: 5, 1: null, 2: undefined, 3: {name: "anpoly", age: undefined, sex: null}, 4: [6, 3, 4], 5:ƒ ()}

2.深拷贝

var source2 = {0:1, 1:null, 2:undefined, 3:{name: 'anjou', age: undefined, sex: null}, 4:[2, 3, 4], 5: function() {}}
var target = JSON.parse(JSON.stringify(source2))
target['0'] = 5
target['3'].name = 'anpoly'
target['4'][0] = 6
console.log(source2)  // {0: 1, 1: null, 2: undefined, 3: {name: "anjou", age: undefined, sex: null}, 4: [2, 3, 4], 5:ƒ ()}
console.log(target)   // {0: 1, 1: null, 3: {name: "anpoly", sex: null}, 4: [6, 3, 4]}

通过上面的这些拷贝技巧的分析,我们发现没有一个可以做到比较完整的深拷贝。那要如何实现一个数组或者一个对象的深拷贝呢? 接下来我们将写一个简单的克隆函数来实现数组与对象的深拷贝。

// 克隆函数
    var source = [1, null, undefined, {name: 'anjou', age: undefined, sex: null}, [2, 3, 4], function() {}]
    function deepCopy(data) {
        if (typeof data !== 'object' || data == null) return data
        var newData = data instanceof Array ? [] : {}
        for (var key in data) {
            newData[key] = typeof data[key] === 'object' ? (data[key] === null ? null : deepCopy(data[key])) : data[key]
        }
        return newData
    }
    var target = deepCopy(source)
    target[0] = 5
    target[3].name = 'anpoly'
    target[4][0] = 6
    console.log(source)  // [1, null, undefined, {name: 'anjou', age: undefined, sex: null}, [2, 3, 4], ƒ ()]
    console.log(target)  // [5, null, undefined, {name: 'anpoly', age: undefined, sex: null}, [6, 3, 4], ƒ ()]
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值