深淺拷貝

參考:

  JavaScript專題之深淺拷貝。javascript

 

淺拷貝:

  淺拷貝就是拷貝指向對象的指針,所以,若是其中一個對象改變了這個地址,就會影響到另外一個對象。
java

  在 js 中,若是與深拷貝一塊兒說起的話,就意味着只在首層上進行一次徹底(資源)複製,若是首層內部存在引用類型的對象,則這個對象僅僅是 copy 了內存地址而已。
數組

  

  經常使用的淺拷貝以及用法如數組中的 arr.concat()、arrr.slice(), 常規對象中的 Object.assign({},sourceObj)、{...sourceObj} 。
函數

  js 實現起來也簡單:post

var shallowCopy = function(obj) {
  // 不是對象不 Copy
  if (typeof obj !== 'object') return;
  // 根據obj的類型判斷是新建一個數組仍是對象
  var newObj = obj instanceof Array ? [] : {};
  // 遍歷obj,而且判斷是obj的屬性才拷貝
  for (var key in obj) {
    if (obj.hasOwnProperty(key)) newObj[key] = obj[key];
  }

  return newObj;
}

 

深拷貝:

  深拷貝就是指徹底的拷貝一個對象,即便嵌套了對象,二者也相互分離,修改一個對象的屬性,也不會影響另外一個。性能

 

  經常使用的方法:ui

  • JSON.parse(JSON.stringify(obj)),不過這個方法有不少缺點:
      1.若是 obj 中包含事件對象,結果中時間將只會以字符串形式出現;
      2.若是 obj 中包含 RegExp、Error對象,則結果中只獲得空對象({});
      3.若是 obj 中包含函數、undefined,則結果中會丟棄;
      4.若是 obj 中包含 NaN、Infinity、-Infinity,則結果中會變成 null;
      5.若是對象中存在循環引用,將沒法實現正確拷貝;
      6.若是 obj 中的有對象是構造函數生成的,則結果中該對象的 constructor 將會丟失,變成 Object;
  • lodash 中的 cloneDeep 函數;
  • Jquery 中 $.extend([deep], target, object1 [, objectN]);
  • facebook 的 Immutable.js; Immutable.js瞭解一下?


  咱們也能夠經過 js 本身實現一個:
spa

var deepCopy = function(obj) {
  // 不是對象不 Copy
  if (typeof obj !== 'object') return;
  // 根據obj的類型判斷是新建一個數組仍是對象
  var newObj = obj instanceof Array ? [] : {};

  for (var key in obj) {
    if (obj.hasOwnProperty(key)) {
      // 判斷屬性是否是 object 以決定要不要遞歸
      newObj[key] = typeof obj[key] === 'object' ? deepCopy(obj[key]) : obj[key];
    }
  }
  return newObj;
}

 

 

  可是,上述深拷貝中仍然存在諸多問題:指針

  1. 性能上,深拷貝由於使用了遞歸,故必不如淺拷貝;
  2. 循環引用,若是對象的a屬性和b屬性互相有都掛載到本身的子屬性上就會棧溢出;
相關文章
相關標籤/搜索