iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 30
0
自我挑戰組

利用30分鐘~想一個前端問題系列 第 30

利用30分鐘~想一個前端問題 Day30-deepClone

  • 分享至 

  • xImage
  •  

deepClone

Creates a deep clone of an object. Clones primitives, arrays and objects, excluding class instances.

Use recursion.
Check if the passed object is null and, if so, return null.
Use Object.assign() and an empty object ({}) to create a shallow clone of the original.
Use Object.keys() and Array.prototype.forEach() to determine which key-value pairs need to be deep cloned.
If the object is an Array, set the clone's length to that of the original and use Array.from(clone) to create a clone.

深拷貝物件,拷貝原形 和 陣列 物件 類別

1.使用遞歸
2.確認傳遞物件是否是空值,如果是,回傳空值
3.使用 Object.assign() 和 空的物件 {} 先做淺拷貝。
4. 使用 Object.keys() 和 Array.prototype.forEach() 決定
屬性-值對 是否需 深拷貝
5.如果是陣列,先設定陣列長度,再使用 Array.from 複製

const deepClone = obj => {
  if (obj === null) return null;
  let clone = Object.assign({}, obj);
  Object.keys(clone).forEach(
    key => (clone[key] = typeof obj[key] === 'object' ? deepClone(obj[key]) : obj[key])
  );
  if (Array.isArray(obj)) {
    clone.length = obj.length;
    return Array.from(clone);
  }
  return clone;
};
//EXAMPLES
const a = { foo: 'bar', obj: { a: 1, b: 2 } };
const b = deepClone(a); // a !== b, a.obj !== b.obj

分析點

1.深拷貝

通常用在兩個情況

1.有個對象傳給一個函數,不放心它會不會隨便修改這個對象,所以要 複製一個
2.想修改一個對象但又不想影響原來對象

Object.assign({}, obj1)的意思是先建立一個空物件,但是還沒辦法做最深層的複製

var obj = { a: 1 };
var copy = Object.assign({}, obj);
console.log(copy); // { a: 1 }

因為Object.assign跟我們手動複製的效果相同
所以一樣只能處理深度只有一層的物件
沒辦法做到真正的 Deep Copy

完全複製整個物件,包含 key 為 symbol 或值為 undefined 的屬性
考慮物件循環引用的可能性,因為 考慮值為 null 的情況,typeof null 會得到 object 所以 要特別 if (obj === null) return null;

2.Array.from

Array.from() : 將偽陣列物件或可遍歷物件轉換為真陣列

如果一個物件的所有鍵名都是正整數或零,並且有length屬性,那麼這個物件就很像陣列,語法上稱為“類似陣列的物件”(array-like object),即為偽陣列。

let arr = Array.from('juejin'); 
console.log(arr); //["j", "u", "e", "j", "i", "n"]

參考文章

關於 JS 中的淺拷貝和深拷貝

How to Deep clone in javascript


上一篇
利用30分鐘~想一個前端問題 Day29-matches
系列文
利用30分鐘~想一個前端問題30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言