JavaScript對象的深拷貝

前言

-路漫漫其修遠兮,我將上下而求索。前端

在JavaScript數據類型分爲基礎類型和引用類型,而引用類型又稱爲對象,可見了解對象是咱們真正掌握JavaScript語言的必備技能。本章主要與你們一塊兒去探索JavaScript對象的一些常常被咱們忽略的以及難以理解的知識。好了,廢話很少說讓咱們一塊兒進入JavaScript對象的世界吧。編程

基本概念

  • 我的理解:深淺拷貝在JavaScript中只是對於引用類型來講的,由於在JavaScript中基本數據類型是經過值傳遞的,因此他們不存在深拷貝一說。
  • 對象的淺拷貝:即只複製對象在棧內存中的保存的地址值,例如咱們直接用賦值符號拷貝另外一個對象的值。
  • 對象的深拷貝:複製對象存在堆內存中的實際值而且從新在棧內存中生成一份指向新堆內存中的地址值。
  • 緣由:JavaScript中的引用類型的數據是被存放在堆內存中的,他們在棧內存中的變量只是保存了一個指向對堆內存中值的指針(相似與c中的指針),所以咱們在訪問引用類型的數據時只能先從棧中取出對象的指針地址,而後纔會從堆內存中取得對象的數據。這也是JavaScript對象用賦值符號只能複製指針地址的緣由。

爲什麼進行對象深拷貝

  • 若是隻是對對象數據類型進行簡單的淺拷貝,則新複製的值和老值會共用堆內存中的數據,致使值不肯定性,例如:
let a={
    val:"test"
}
console.log(a.val)//"test"
let b=a
b.val="test2"
console.log(a.val)//"test2"
console.log(b.val)//"test2"
複製代碼

這也是致使前端顯示異常的根本緣由之一json

  • 提升代碼可維護性,多人合做開發時,共用某份是對象類型的數據若是隻進行簡單的淺拷貝則很影響他人。

深拷貝的方法

  • JSON.stringfy() => JSON.parse() 即將一個對象先解析爲json 字符串而後再解析
let a={
    val:'test'
}
let b=JSON.parse(JSON.stringfy(a))
複製代碼

優勢:操做簡單。數組

缺點:1.若是對象很大會佔用內存 2.對於複雜的對象類型(即屬性是諸如 Map, Set, RegExp, Date, ArrayBuffer,function和其餘內置類型),在進行序列化時會丟失。 丟失屬性。3.沒法進行對象的循環處理。bash

  • 使用object.assign()來實現:
let originobj= {
  'name': 'test',
  'weight': 50
};
let newobj = Object.assign({}, originobj, {
  'test': '111'
});
newobj.age = 60;
console.log('originobj', originobj); //{name: "test", weight: 50}
console.log('newobj', newobj); //{name: "test", weight: 50, test: "111", age: 60}

複製代碼

優勢:方便快捷 不會丟失原數據 缺點:只能複製簡單的對象(),即Object.assign()拷貝的只是屬性值 注意:若是對象中的屬性仍是對象則Object.assign()不會進行值拷貝,只能進行引用拷貝編程語言

  • 爲了解決JSON和assign複製帶來的問題,咱們能夠採用循環遞歸複製,即在遍歷賦值對象屬性的時候,遇到屬性是引用類型的,則把這個屬性展開賦值,以下代碼所示:
function cloneDeep(newobj={},originObj){
    for(let key in originObj){
        //判斷是不是對象類型
        if(originObj[key] && originObj[key] instanceof object){
            //遞歸將對象類型賦值給新數組
            newobj[key] = cloneDeep(originObj[key])
        }else{
            newobj[key] = originObj[key]
        }
    }
    return newobj
}
let obj = {a:{b:'test'},c:"test2"}
//此時徹底copy了obj的值
let obj1 = cloneDeep(obj)//{a:{b:'test'},c:"test2"}
複製代碼

總結

在編程的世界中熟悉某一門語言的基本要求就是掌握這門語言定義的數據類型,不一樣的語言中所定義的數據類型每每不一樣。這也是咱們同時掌握多中編程語言的難點。但幸運的是他們底層設計原理都是相互借鑑的,這也成爲了咱們可以掌握奪門語言的關鍵點之一。ui

相關文章
相關標籤/搜索