1. 程式人生 > 其它 >JS物件深拷貝-with JSON

JS物件深拷貝-with JSON

如何使用JSON進行物件的深拷貝

前置知識:

1)JSON中沒有undefined值;在序列化時,會跳過值為undefined的屬性。

2)JSON中沒有函式的概念;在序列化時,會跳過值為函式的屬性。

我們需要針對值為undefined或函式的屬性進行處理,如何處理?

大體上在序列化、反序列化(解析)時傳入過濾器(分別參考JSON.stringify()的第二個引數以及JSON.parse()方法的第二個引數)。

細節處理知識:

1)如何複製一個函式?

function a() {}
const b = new Function("return " + a.toString())();

2)按照複製函式的知識點,我們可以將函式以字串的形式存於JSON中;這樣做需要解決一個問題:

在反序列化(解析)時,如何區分一般字串與轉變成字串的函式字串?

我這裡的方法就是:在將函式轉變為字串時,為其新增特定字元作為字首,如“$” (這裡需要約定一般字串不能以$開頭)。

例子:

/**
 * 序列化過濾處理.
 */
 function replacer(key, value) {
  if (typeof value === "function") {
    // 將方法轉換成字串,以符號$作為方法標識
    return "$" + value.toString();
  } else if (typeof value === "undefined") {
    // 直接將undefined值的屬性變成null值。
return null; } return value; } /** * 反序列化(解析)過濾處理 */ function reviver(key, value) { if (typeof value === 'string') { if (value[0] === '$') { // 遇到字首為$的字串將被嘗試轉變為函式。 try { return new Function('return ' + value.slice(1))(); } catch (error) { console.error("字首為$的字串轉變為函式失敗");
// 直接以字串形式返回。 return value; } } } return value; } let car = { name: '五菱巨集光', owner: { age: 18, name: '李四', gender: undefined }, year: 2018, run: function () { console.log("閃電漂移..."); } } const copyCar = JSON.parse(JSON.stringify(car, replacer), reviver);

大體上是這麼個思路,

如果有需要可增添一些細節處理,比如:複製方法名、將原本undefined值的元素在複製後仍為undefined等。

如果需要將特定的內建物件進行復制,比如Date等也可以通過類似的手段進行處理。

 

人人須日日改過,一旦無過可改,即一日無步可過矣。若發現不妥的點請務必指出,非常感謝。