JSON.parse,JSON.stringify 深浅拷贝的缺陷

经常使用 JSON.parse, JSON.stringify 的小伙伴都知道,他们两个可以用于深拷贝对象,但是可能会不太注意一些缺陷,是又一次我使用他们去深拷贝对象,我发现有些属性莫名其妙的丢失了,之前没有太深究其弊端,今天趁着有空深究一下这些弊端。

首先我们来看下代码:

let deepClone = function(obj) {
    return JSON.parse(JSON.stringify(obj))
let a = {
    name: 'Ken',
    age: 18,
    hobbit: ['dance', 'sing', {type: 'sports', value: 'run'}],
    schoolData: {
        grades: 'A',
    run: function() {},
    walk: undefined,
    fly: NaN,
    cy: null
let b = deepClone(a)
console.log("b", b)
    age: 18,
    cy: null,
    fly: null,
    hobbit: (3) ["dance", "sing", {…}],
    name: "Ken",
    schoolData: {grades: "A"},

对比原有的对象,我们可以知道:

  • 不会拷贝对象上的 value 值为 undefined 和 函数的键值对
  • NaN,无穷大,无穷小会被转为 null
  • 自定义对象测试

    let Ken = function() {
        this.name = "Ken"
    Ken.prototype.walk = function() {
        console.log("walk")
    let KenNaNa = function() {
        Ken.call(this, arguments)
        this.name = "KenNaNa"
    let tempFunc = function() {}
    tempFunc.prototype = Ken.prototype
    KenNaNa.prototype = new tempFunc()
    KenNaNa.prototype.age = "18"
    KenNaNa.prototype.run = function() {
        console.log("run")
    Object.defineProperty(KenNaNa.prototype, "contructor", {
        value: KenNaNa,
        enumerable:false
    let kenNaNa = new KenNaNa()
    let copyKenNaNa = JSON.parse(JSON.stringify(kenNaNa))
     Ken {age: "18", run: ƒ, contructor: ƒ}
    console.log(copyKenNaNa.constructor); // ƒ Object() { [native code]}
    console.log(copyKenNaNa.age) // undefined
    console.log(copyKenNaNa.run()) // is not function
    console.log(copyKenNaNa.walk()) // is not function 
    console.log(copyKenNaNa.toString()) // "[object Object]"
    
  • 无法获取原型上面的方法,属性,只能获取 Object 原型的内容
  • var date = new Date()
    var copy = JSON.parse(JSON.stringify(date))
    console.log("copy", copy) // "2021-01-14T06:47:12.337Z"
    
  • 取不到值为 undefined 的 key
  • NaN 和 无穷大,无穷小转变为 null
  • 取不到原型的内容
  • date 对象转变为 date 字符串
  • 循环引用会报错

    Symbol() 会丢失

    分类:
    前端
  •