1. 程式人生 > >javascript 賦值 淺拷貝 深拷貝

javascript 賦值 淺拷貝 深拷貝

    let originObj = {
        name: 'Lili',
        age: 12,
        families: ['Jhon', 'Linda', 'Mike']
    }
    // 賦值 (賦值獲得的是指向原物件的一個地址指標,它和原物件操作的是同一個資料來源,任何操作都會互相影響)
    let copyObj = originObj
    copyObj.age = 24
    console.log('賦值改變之後的原始值',originObj) 

    // 淺拷貝 (淺拷貝,拷貝的是某個物件,卻不拷貝某個物件的子物件,因此,操作基本型別的資料,不會影響資料來源,但是操作引用型別的資料,同時也會改變資料來源)
    // 淺拷貝的幾種實現  Object.assign()  Array.prototype.concat()  Array.prototype.slice()
    function shallowCopy(obj) {
        let result = {} ;
        for(var prop in obj) {
            if(obj.hasOwnProperty(prop)) {
                result[prop] = obj[prop]
            }
        }
        return result;
    }

    let shaollowCopyObj = shallowCopy(originObj)
    shaollowCopyObj.age = '12'
    shaollowCopyObj.families[0] = 'shallowCopyObj'
    console.log('淺拷貝改變之後的原始值',originObj)

    // 深拷貝
    // JSON.parse(JSON.stringify()) 將一個物件通過JSON.stringify 轉換為字串再通過 JSON.parse 轉換為物件實現的是深拷貝
    // 但是這裡不能處理函式,因為 JSON.stringify 方法是將js的一個值(物件或者是陣列) 轉換為js字串
    // 1.定義檢測資料型別的功能函式
    function checkedType (target) {
        return Object.prototype.toString.call(target).slice(8, -1)
    }
    // console.log(checkedType(originObj))  //[object object]
    function deepCopy (target) {
        let result
        let targetType = checkedType(target)
        if(targetType === 'Object') {
            result = {}
        } else if (targetType === 'Array') {
            result = []
        } else {
            return target
        }

        for(let i in target) {
            let value = target[i]
            if(checkedType(value) === 'Object' || checkedType(value) === 'Array') {
                result[i] = deepCopy(value)
            } else {
                result[i] = value
            }
        }

        return result;
    }
    let deepCopyObj = deepCopy(originObj)
    deepCopyObj.age = 44;
    deepCopyObj.families[2] = 'deppCopyObj'
    console.log('深拷貝改變之後的原始值', originObj)