js 基礎加固之複製

shijf發表於2021-03-04

js 深複製方法

/**
 * js 深複製方法
 * @param target 目標物件
 * @param source 源物件
 */
function deepCopy(target, source) {
    // 透過遍歷拿到source中多有的屬性
    for (let key in source){
        // 2. 去除當前遍歷到的屬性對應的取值
        let sourceValue = source[key]

        // 3. 判斷西啊是否是基礎資料型別
        if (sourceValue instanceof Object) {
            console.log(sourceValue)
            // 新建一個需要進一步深複製的建構函式(一開思考沒有加這個)
            let subTarget = new sourceValue.constructor;
            target[key] = subTarget
            deepCopy(subTarget, sourceValue)
        } else {
            target[key] = sourceValue
        }

    }
}

// 利用 MessageChannel

function deepCopy(obj) {

    return new Promise((resolve) => {

        const { port1, port2 } = new MessageChannel();

        port2.onmessage = ev => resolve(ev.data);

        port1.postMessage(obj);

    });

}

deepCopy(obj).then((copy) => {           // 請記住`MessageChannel`是非同步的這個前提!

    let copyObj = copy;

    console.log(copyObj, obj)

    console.log(copyObj == obj)

});

// json
const obj = {name: 'llx123'}
const obj2 = { ...obj }
const obj3 = JSON.parse(JSON.stringify(obj))

// array

const arr= [{name: 'llx123'}]
const [ ...arr2 ] = arr
const arr3 = []
arr3.concat(arr)

淺複製

  1. Object.create() 方法
    作者:liwuwuzhi
    連結:www.jianshu.com/p/28d85bebe599
    來源:簡書
    著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。
var triangle = {a: 1, b: 2, c: 3};

function ColoredTriangle() {
  this.color = 'red';
}

//ColoredTriangle.prototype = triangle;  //ColoredTriangle.prototype.constructor === ColoredTriangle// false
Object.assign(ColoredTriangle.prototype, triangle) //ColoredTriangle.prototype.constructor === ColoredTriangle// true

var c = new ColoredTriangle();

此時的c,如下圖:
js 基礎加固之深複製

// 此處重點理解 Object.create() 的含義,是將 原型指向自己
var originProto = Object.getPrototypeOf(c); // 獲取到的是 c的 __proto__
var originProto2 = Object.create(originProto);

// 複製操作,因為 assign 方法不會複製 c 的 原型物件
 var deepC = Object.assign(originProto2, c)

// 第二種方法(推薦)
// Object.getPrototypeOf() 得到的是 c 物件的原型,然後作為第一個引數,所以會在新物件c2 的原型上。
// Object.getOwnPropertyDescriptors() 得到是 c 物件自身的可列舉屬性,作為第二個引數,放在 c2 的例項上。
//  https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptors#%E6%B5%85%E6%8B%B7%E8%B4%9D%E4%B8%80%E4%B8%AA%E5%AF%B9%E8%B1%A1
var c2 = Object.create(Object.getPrototypeOf(c), Object.getOwnPropertyDescriptors(c));
本作品採用《CC 協議》,轉載必須註明作者和本文連結
支付寶領個紅包就是對我最大的讚賞了

相關文章