浅拷贝与深拷贝

144 阅读2分钟

浅拷贝

法1:直接赋值

let obj = {
    name: 'Lucy',
    age: 18,
    adult: true,
    girlFriend: null,
    height: undefined,
    hobby: ['吃饭', '睡觉', '读书'],
    brother: {
        name: 'Tom',
        age: 20,
    },
    eat: function () {
        console.log('西瓜')
    },
}
let obj1 = obj
console.log(obj1 === obj)//true
obj1.age = 20
console.log(obj1 === obj)//true

法2:Object.asign()

let obj = {
    name: 'Lucy',
    age: 18,
    adult: true,
    girlFriend: null,
    height: undefined,
    hobby: ['吃饭', '睡觉', '读书'],
    brother: {
        name: 'Tom',
        age: 20,
    },
    eat: function () {
        console.log('西瓜')
    },
}
let obj1 = Object.assign(obj, {})
console.log(obj1 === obj)//true
obj1.age = 20
console.log(obj.age)//20
console.log(obj1 === obj)//true

法3:Array.prototype.slice()

let arr = [1, '哈哈', true, undefined]
let newArr =arr.slice(0)
console.log(newArr)//[ 1, '哈哈', true, undefined ]
console.log(newArr == arr)//false
console.log(newArr === arr)//false
newArr[1] = '嘿嘿'
console.log(newArr)//[ 1, '嘿嘿', true, undefined ]

法4:Array.prototype.concat()

let arr = [1, '哈哈', true, undefined]
let newArr =arr.concat()
console.log(newArr)//[ 1, '哈哈', true, undefined ]
console.log(newArr == arr)//false
console.log(newArr === arr)//false
newArr[1] = '嘿嘿'
console.log(newArr)//[ 1, '嘿嘿', true, undefined ]

法5:扩展运算符...

let arr = [1, '哈哈', true, undefined]
let newArr = [...arr]
console.log(newArr)//[ 1, '哈哈', true, undefined ]
console.log(newArr == arr)//false
console.log(newArr === arr)//false
newArr[1] = '嘿嘿'
console.log(newArr)//[ 1, '嘿嘿', true, undefined ]

法6:jQuery.extend()

    <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
    <script>
        console.log($)
        let obj = {
            name: 'Lucy',
            age: 18,
            adult: true,
            girlFriend: null,
            height: undefined,
            saiHi: Symbol('A'),
            hobby: ['吃饭', '睡觉', '读书'],
            brother: {
                name: 'Tom',
                age: 20,
            },
            eat: function () {
                console.log('西瓜')
            },
        }
        let obj1 = $.extend({}, obj)
        console.log(obj1)
        console.log(obj1 === obj)//false
        console.log(obj1.prototype === obj.prototype)//true
        console.log(typeof Symbol('A'))//symbol
    </script>

image.png

深拷贝

法1:JSON.parse(JSON.stringify())

这种方法会忽略:undefined、Symbol和函数

let obj = {
    name: 'Lucy',
    age: 18,
    adult: true,
    girlFriend: null,
    height: undefined,
    let obj = {
    name: 'Lucy',
    age: 18,
    adult: true,
    girlFriend: null,
    height: undefined,
    sayHi:Symbol('A'),
    hobby: ['吃饭', '睡觉', '读书'],
    brother: {
        name: 'Tom',
        age: 20,
    },
    eat: function () {
        console.log('西瓜')
    },
}
let obj1 = JSON.parse(JSON.stringify(obj))
console.log(obj1)
console.log(obj1 === obj)//false
obj.name = 'Jane'
console.log(obj1.name)//lucy
obj1.age = 25
console.log(obj.age)//18

image.png

法2:循环递归

let obj = {
    name: 'Lucy',
    age: 18,
    adult: true,
    girlFriend: null,
    height: undefined,
    hobby: ['吃饭', '睡觉', '读书'],
    brother: {
        name: 'Tom',
        age: 20,
    },
    eat: function () {
        console.log('西瓜')
    },
}

function cloneObj(newObj, obj) {
    for (let key in obj) {
        if (obj[key] instanceof Array) {
            newObj[key] = []
            cloneObj(newObj[key], obj[key])
        } else if (obj[key] instanceof Object) {
            newObj[key] = {}
            cloneObj(newObj[key], obj[key])
        } else {
            newObj[key] = obj[key]
        }
    }
}

let newObj = {}
cloneObj(newObj, obj)
console.log(newObj)
console.log(newObj === obj)//false
obj.name = 'Alice'
console.log(newObj.name)//Lucy

image.png

递归实现深拷贝---代码优化

let obj = {
    name: 'Lucy',
    age: 18,
    adult: true,
    girlFriend: null,
    height: undefined,
    hobby: ['吃饭', '睡觉', '读书'],
    brother: {
        name: 'Tom',
        age: 20,
    },
    eat: function () {
        console.log('西瓜')
    },
}
function cloneObj(obj){
    if (typeof obj !== 'object') return obj
    let newObj = Array.isArray(obj) ? [] : {}
    for (let key in obj) {
        newObj[key] = cloneObj(obj[key])
    }
    return newObj
}
console.log(cloneObj(obj))

image.png

法3: _.cloneDeep()

// ◆首先在终端下包 npm i lodash
const _ = require('lodash')

let obj = {
    name: 'Lucy',
    age: 18,
    adult: true,
    girlFriend: null,
    height: undefined,
    hobby: ['吃饭', '睡觉', '读书'],
    brother: {
        name: 'Tom',
        age: 20,
    },
    eat: function () {
        console.log('西瓜')
    },
}

let obj1 = _.cloneDeep(obj)
console.log(obj1)
console.log(obj1 === obj)//false

image.png

法4:jQuery.extend()

    <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
    <script>
        console.log($)
        let obj = {
            name: 'Lucy',
            age: 18,
            adult: true,
            girlFriend: null,
            height: undefined,
            hobby: ['吃饭', '睡觉', '读书'],
            brother: {
                name: 'Tom',
                age: 20,
            },
            eat: function () {
                console.log('西瓜')
            },
        }
        
        let obj1 = $.extend(true, {}, obj)
        console.log(obj1)
        console.log(obj1 === obj)//false
        console.log(obj1.prototype === obj.prototype)//true
    </script>

image.png