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 并没有复制成功,因为它们有特殊的构造函数。