關於js的淺拷貝與深拷貝

原文地址: http://www.silenceboy.com/201...

淺拷貝和深拷貝只針對像Object, Array這樣的複雜對象的.簡單來講,淺拷貝只拷貝一層對象的屬性,而深拷貝則遞歸拷貝了全部層級。安全

淺拷貝

經過 Object.assign 來實現淺拷貝。

let a = {
    num: 1
}
let b = Object.assign({}, a)
a.num = 2
console.log(b.num) // 1

經過展開運算符(…)來實現淺拷貝

let a = {
    num: 1
}
let b = {...a}
a.num = 2
console.log(b.num) // 1

經過屬性賦值來實現淺拷貝:

const obj = { a:1, arr: [2,3] };
const shallowObj = shallowCopy(obj);

function shallowCopy(src) {
  var dst = {};
  for (var prop in src) {
    if (src.hasOwnProperty(prop)) {
      dst[prop] = src[prop];
    }
  }
  return dst;
}

該方法體現了淺拷貝的問題.由於淺拷貝只會將對象的各個屬性進行依次拷貝,並不會進行遞歸拷貝,而 JavaScript 存儲對象都是存地址的,因此淺拷貝會致使 obj.arr 和 shallowObj.arr 指向同一塊內存地址.框架

致使的結果就是:函數

shallowObj.arr[1] = 5;
obj.arr[1]   // = 5

這種狀況就須要用到深拷貝了.code

深拷貝

經過JSON序列化實現深拷貝

你不知道的JavaScript(上)
許多JavaScript框架都提出了本身的解決辦法,可是Javascript應該採用那種方法做爲標準吶? 在很長一段時間裏,這個問題都沒有明確的答案.對於JSON安全(也就是說能夠被序列化爲一個JSON字符串而且能夠根據這個字符串解析出一個結構和值徹底同樣的對象)的對象來講,有一種巧妙的複製方法:
var newObj = JSON.parse(JSON.stringify(someObj));

固然,這種方法須要保證對象是JSON安全的,因此只適用於部分狀況.對象

該方法的侷限性:遞歸

  1. 會忽略 undefined
  2. 會忽略 symbol
  3. 不能序列化函數
  4. 不能解決循環引用的對象

遞歸完成深拷貝

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;
}
相關文章
相關標籤/搜索