clone(obj)

// truly exact copy of `obj`, including all properties: 
// • enumerable and non-enumerable
// • data properties, setters/getters
// with the right [[Prototype]].
function clone(obj) {
    return Object.create(
        Object.getPrototypeOf(obj),                // same [[Prototype]] as obj.
        Object.getOwnPropertyDescriptors(obj)      // clone all own members.
    );
}

💈範例:

雖然可以用 clone() 複製物件,但兩個物件之間,依然有可能存在些微差異,例如:下例的 a 是一個 Array,但 clone() 之後的 a2 就不是 Array❗️

// an array
let a = [1,2,3];

// an object
const o = {
    name: 'Joe',
    age: 25,
    array: [1,2,3],
    hobbies: {
        sports: ['badminton', 'baseball'],
        games: ['zelda', 'poker']
    }
}

// clone
let a2 = clone(a);
let o2 = clone(o);

// change some properties
o.array = [];                // ⭐ now, `o.array !== o2.array`❗
o.hobbies.games = [];        // ⭐ since `o.hobbies === o2.hobbies`,
                             //   `o.hobbies.games === o2.hobbies.games`❗

// ---------------------- console ----------------------------------
[
    a,                       // [ 1, 2, 3 ]
    typeof a,                // 'object'
    Array.isArray(a),        // true
    
    a2,                      // Array { '0': 1, '1': 2, '2': 3 }
    typeof a2,               // 'object'
    Array.isArray(a2),       // false (a2 is NOT an array❗)

    JSON.stringify(o),
    // {
    //     name: "Joe",
    //     age : 25,
    //     array  : [],      // ⭐ `o.array` overwritten❗
    //     hobbies: {
    //         sports:["badminton","baseball"],
    //         games :[]     // ⭐ this one has changed.
    //     }
    // }
    
    JSON.stringify(o2),
    // {
    //     name: "Joe",
    //     age : 25,
    //     array  : [1,2,3], // ⭐ `o2.array` remains intact.
    //     hobbies: {
    //         sports:["badminton","baseball"],
    //         games :[]     // ⭐ this (same) one has changed too.
    //     }
    // }
    
].forEach(x => log(x));

Last updated