1. 程式人生 > 其它 >手寫深淺拷貝

手寫深淺拷貝

參考
來源:https://www.bilibili.com/video/BV1sN411974w?p=2
細講:

JavaScript 資料型別和資料結構 - JavaScript | MDN (mozilla.org)

(11條訊息) JavaScript資料型別的儲存方法詳解_Bminem的部落格-CSDN部落格

(11條訊息) 精緻的js深淺拷貝(面試題有關)_輕嘆年華逝,的部落格-CSDN部落格_js深淺拷貝面試

前端面試題——物件的深淺拷貝 - 知乎 (zhihu.com)

[JavaScript 深拷貝(deep copy)和淺拷貝(shallow copy) - 隙游塵 - 部落格園 (cnblogs.com)](

https://www.cnblogs.com/xiyouchen/p/10366236.html#:~:text=淺拷貝 的意思是,新變數中存在一些仍然與原來的變數有關聯的值。 JavaScript,資料型別. 原始資料型別 (有的資料叫做基本資料型別):數字、字串、布林值、undefined、null. 這些值被賦值後就和對應的變數繫結在一起。如果你拷貝這些變數,就是實實在在的拷貝。)

1. 知識

資料型別

  • 7 種原始型別,使用typeof運算子檢查:
    • undefinedtypeof instance === "undefined"
    • Booleantypeof instance === "boolean"
    • Numbertypeof instance === "number"
    • Stringtypeof instance === "string
    • BigInttypeof instance === "bigint"
    • Symboltypeof instance === "symbol"
    • nulltypeof instance === "object"
  • Objecttypeof instance === "object"。任何 constructed 物件例項的特殊非資料結構型別,也用做資料結構:new Object,new Array,new Map,new Set,new WeakMap,new WeakSet,new Date,和幾乎所有通過 new keyword 建立的東西。

​ 如果我們希望檢查任何從 Object 派生出來的結構型別,使用 typeof 是不起作用的,因為總是會得到 "object"。檢查 Object 種類的合適方式是使用 instanceof 關鍵字。但即使這樣也存在誤差。

引用資料型別

基礎資料型別存在棧中,而引用資料型別存在堆中

賦值

對引用資料型別,賦值是單純的引用

淺拷貝(引用資料型別之間的直接賦值即可實現)

對引用資料型別,淺拷貝前後會互相影響(拷貝的是記憶體的地址)

深拷貝(拓展運算子、slice、concat、Array.from)

對引用資料型別,深拷貝會建立新的堆

2. 手寫

// 淺拷貝
 var easyCopy = function ( extendObj ) {
        var newObj = extendObj.constructor === Array ? [] : {};
        if (typeof extendObj != 'object') return;
        for (var key in extendObj) {
            if (extendObj.hasOwnProperty(key)) {
                newObj[key] = extendObj[key];
            }
        }
        return newObj
    };

    var obj2 = {
        tall: 1.8,
        weight: 75
    }

    var obj1 = easyCopy( obj2 );

    console.log( obj1 );
// 深拷貝
// 丐版
var newObj = JSON.parse( JSON.stringify( someObj ) );
// 遞迴經典實現
function deepCopy(obj){
    //判斷是否是簡單資料型別,
    if(typeof obj == "object"){
        //複雜資料型別
        var result = obj.constructor == Array ? [] : {};
        for(let i in obj){
            result[i] = typeof obj[i] == "object" ? deepCopy(obj[i]) : obj[i];
        }
    }else {
        //簡單資料型別 直接 == 賦值
        var result = obj;
    }
    return result;
}