• 深浅拷贝


    浅拷贝

    1、Object.assign
    let a = {
      age: 1
    }
    let b = Object.assign({}, a)
    a.age = 2
    console.log(b.age) // 1
    
    2、展开运算符 ...

    let a = {
    age: 1
    }
    let b = { ...a }
    a.age = 2
    console.log(b.age) // 1

    深拷贝

    1、JSON.parse(JSON.stringify(object))
    let a = {
      age: 1,
      jobs: {
        first: 'FE'
      }
    }
    let b = JSON.parse(JSON.stringify(a))
    a.jobs.first = 'native'
    console.log(b.jobs.first) // FE
    

    但是该方法也是有局限性的:

    会忽略 undefined
    会忽略 symbol
    不能序列化函数
    不能解决循环引用的对象

    let obj = {
      a: 1,
      b: {
        c: 2,
        d: 3,
      },
    }
    obj.c = obj.b
    obj.e = obj.a
    obj.b.c = obj.c
    obj.b.d = obj.b
    obj.b.e = obj.b.c
    let newObj = JSON.parse(JSON.stringify(obj))
    console.log(newObj)
    
    

    如果你有这么一个循环引用对象,你会发现并不能通过该方法实现深拷贝
    在遇到函数、 undefined 或者 symbol 的时候,该对象也不能正常的序列化

    let a = {
      age: undefined,
      sex: Symbol('male'),
      jobs: function() {},
      name: 'yck'
    }
    let b = JSON.parse(JSON.stringify(a))
    console.log(b) // {name: "yck"}
    

    你会发现在上述情况中,该方法会忽略掉函数和 undefined 。
    但是在通常情况下,复杂数据都是可以序列化的,所以这个函数可以解决大部分问题。

    2、如果所需拷贝的对象含有内置类型并且不包含函数,可以使用 ####MessageChannel
    function structuralClone(obj) {
      return new Promise(resolve => {
        const { port1, port2 } = new MessageChannel()
        port2.onmessage = ev => resolve(ev.data)
        port1.postMessage(obj)
      })
    }
    
    var obj = {
      a: 1,
      b: {
        c: 2
      }
    }
    
    obj.b.d = obj.b
    
    // 注意该方法是异步的
    // 可以处理 undefined 和循环引用对象
    const test = async () => {
      const clone = await structuralClone(obj)
      console.log(clone)
    }
    test()
    
    3、推荐使用 lodash 的深拷贝函数。
    function deepClone(obj) {
      function isObject(o) {
        return (typeof o === 'object' || typeof o === 'function') && o !== null
      }
    
      if (!isObject(obj)) {
        throw new Error('非对象')
      }
    
      let isArray = Array.isArray(obj)
      let newObj = isArray ? [...obj] : { ...obj }
      Reflect.ownKeys(newObj).forEach(key => {
        newObj[key] = isObject(obj[key]) ? deepClone(obj[key]) : obj[key]
      })
    
      return newObj
    }
    
    let obj = {
      a: [1, 2, 3],
      b: {
        c: 2,
        d: 3
      }
    }
    let newObj = deepClone(obj)
    newObj.b.c = 1
    console.log(obj.b.c) // 2
    
  • 相关阅读:
    图像按钮
    提交按钮
    文件上传域
    Python创建虚拟环境
    Typecho使用技巧
    面向对象
    Python语法入门
    Python 基础数据类型
    与用户交互
    MySQL5.7安装教程
  • 原文地址:https://www.cnblogs.com/lyly96720/p/12263742.html
Copyright © 2020-2023  润新知