爲什麼不推薦使用JSON.stringify作深拷貝

咱們知道作深拷貝的時候能夠使用遞歸的方式也能夠用JSON.stringify + JSON.parse這種看起來簡單的方式。
那麼JSON.stringify + JSON.parse這種方式真的好用嗎?
個人經驗告訴我:
JSON.stringify + JSON.parse作深拷貝不安全,並且在大數據量的狀況下存在性能問題,不推薦使用。
下面咱們主要圍繞不安全的問題進行討論,對於性能的問題簡單提下。segmentfault

爲什麼不安全

不安全主要體如今兩個方面:安全

  1. 拷貝過程當中數據失真、丟失
  2. 處理特殊數據時候報錯

數據失真、丟失

數據失真,丟失主要在這幾種類型中有體現函數

Date對象拷貝後數據類型變成字符串

let obj = {
    d: new Date(),
};
console.log(JSON.parse(JSON.stringify(obj)));
// {d: "2020-08-12T04:47:40.958Z"}

正則對象、Error對象拷貝後變成空對象

let obj = {
    r: /\d+/gi,
    e: new Error('an error')
};
console.log(JSON.parse(JSON.stringify(obj)));
// {r: {}, e: {}}

對象裏面的函數和undefined屬性拷貝後屬性丟失

let obj = {
    f: console.log,
    u: undefined
};
console.log(JSON.parse(JSON.stringify(obj)));
// {}

NaN、Infinity、-Infinity拷貝後變爲null

let obj = {
    i: Infinity,
    l: -Infinity,
    n: NaN,

};
console.log(JSON.parse(JSON.stringify(obj)));
// {i: null, l: null, n: null}

改變對象的原型鏈

若是,對象的某個屬性是由構造函數生成的,那麼在拷貝後,他的constructor會指向Object性能

var A = function () {
    this.a = 'a';
};
var a = new A();
var b = JSON.parse(JSON.stringify(a));
console.log(a.constructor, b.constructor);
// ƒ () {this.a = 'a'} ƒ Object() { [native code] }

特殊數據報錯

這個簡單的說就是若是對象中有環的話話就會報錯,最簡單的例子就是大數據

console.log(JSON.parse(JSON.stringify(window)));

這個就會報錯,因此在使用這種方式作深拷貝的時候也要注意環的問題。this

爲什麼性能差

關於性能的問題我這裏很少說,推薦《如何提高JSON.stringify()的性能》這篇文章,這篇文章對JSON.stringify的性能問題說的很清晰,我也很認同。code

參考文檔

相關文章
相關標籤/搜索