js赋值问题

关键字:

JS、引用、赋值、对象复制、数组复制等

前言:

//获取基础参数列表数据
  getEditTableData(event) {
    if(event&&event.length>0){
      event.forEach(item=>{
        delete item.key
      })
    }
    this.fieldConfDtos=event;
  }

  今天在用angular做父子组件的一些数据传递和处理时发现,子组件通过事件传给父组件的数据被父组件处理后影响到了子组件。event是子组件传递过来的参数,这里父组件删除item.key后,发现子组件数据的key也没了。查阅资料后发现是对象数组的引用赋值引起的问题。对象赋值问题踩过几次坑了,这次就系统地记录一下。

  数据类型:https://www.w3school.com.cn/js/pro_js_value.asp

  1、基础数据类型:null、undefined、number、string、boolean

  2、对象类型:Object、array、function、data

  简单结论:基础数据类型是原始值可以直接赋值、而对象类型是引用赋值只是赋值指针。

解决方法:

  根据实际情况使用浅拷贝或深拷贝。这个内容比较复杂和广泛,根据具体情况选用合适的方法。参考https://www.cnblogs.com/panrui1994/p/9378696.html。

  常用方法:

  1、Object.assign()

  (1)是对象类型(2)对象的属性没有引用类型,即都是基础数据类型。如{name:'lucy',obj:{sexy:'m',age:'18'}},这种数据里的obj还是引用类型,复制后依然是共用内存。(3)其他使用注意事项参考https://blog.csdn.net/u012028371/article/details/77817059

  2、迭代递归法 for...in

  (1)适用范围为obj和arry,其他特殊类型不行。

// 判断是否为对象
function isObject(o) {
    return (typeof o === 'object' || typeof o === 'function') && o !== null
}
//测试用例
let test = {
    num: 0,
    str: '',
    boolean: true,
    unf: undefined,
    nul: null,
    obj: {
        name: '我是一个对象',
        id: 1
    },
    arr: [0, 1, 2],
    func: function() {
        console.log('我是一个函数')
    },
    date: new Date(0),
    reg: new RegExp('/我是一个正则/ig'),
    err: new Error('我是一个错误')
}
// 迭代递归法:深拷贝对象与数组
function deepClone(obj) {
    if (!isObject(obj)) {
        throw new Error('obj 不是一个对象!')
    }
    //判断传进来的是对象还是数组
    let isArray = Array.isArray(obj)  
    let cloneObj = isArray ? [] : {}
    //通过for...in来拷贝
    for (let key in obj) {
        cloneObj[key] = isObject(obj[key]) ? deepClone(obj[key]) : obj[key]
    }

    return cloneObj
}
let result = deepClone(test)
console.log(result)
//我们发现,arr 和 obj 都深拷贝成功了,它们的内存引用已经不同了,但 func、date、reg 和 err 并没有复制成功,因为它们有特殊的构造函数。

   

 

posted @ 2019-09-20 15:46  倒带_with  阅读(2205)  评论(0编辑  收藏  举报