1.什么是浅拷贝?
*浅拷贝是创建一个新的对象,如果被拷贝的原始对象中属性数据类型为基本类型(Number、String、Boolen、Undefined、Null),则拷贝的对象和原始对象中的属性值互不影响(就是你的值变了他不变);如果被拷贝的原始对象中属性数据类型为引用类型(Object、Array、Fuction),则拷贝的对象和原始对象中的属性值相互影响(就是你的值变了他也变)
var person = {fname:"John", lname:"Doe", age:25, hobiies:["game","shopping"]}; //浅拷贝 基本数据类型与原对象互不影响 引用类型还是公用一个内存受影响 function shallowClone (obj){ var man = {} for(i in obj){ if(obj.hasOwnProperty(i)){ man[i] = obj[i] } } return man } var boy = shallowClone(person) boy.fname = "Dav" boy.hobiies[0] = "codding" console.log(person) console.log(boy)
2.什么是深拷贝?
*从堆内存中开辟一个新的内存区域存放新对象,将新对象从原始对象上完整拷贝一份出来,修改新对象原始对象不会随之变化
var person = {fname:"John", lname:"Doe", age:25, hobiies:["game","shopping"]}; function deepClone (obj){ var man = {} if(obj === null) return obj // A instanceof B 指的B的prototype是否在A的原型链上 if(obj instanceof Date) return new Date(obj) if(obj instanceof RegExp) return new RegExp(obj) if(typeof obj !== "object") return obj //遍历自身属性 for(i in obj){ //hasOwnProperty 指的是对象的属性或者方法是不是在自己身上而不是在原型链上 if(obj.hasOwnProperty(i)){ man[i] = deepClone(obj[i]) } } return man } var boy = deepClone(person) boy.fname = "Dav" boy.hobiies[0] = "codding" console.log(person) console.log(boy)
*基本类型存在栈内存中,引用类型存在堆内存中。当比较两个基本数据类型的值时,就是比较值而比,比较两个引用数据类型时,它是比较的对象的内存地址
补充:
常用浅拷贝拷贝方法:
方法一: 循环遍历
方法二:扩展运算符
let obj = { name: '张三', age: 26 } let newObj = {...obj} obj.name = '李四' console.log(obj) // obj.name="李四" console.log(newObj)// newObj.name ="张三"
常用深拷贝方法:
方法一:
使用Object.assign(target, source)方法
方法的第一个参数是目标对象,后面的参数都是源对象let data = { a:1 , b:2 } let ccc = {c:3} const newData = Object.assign({}, data, ccc) data = {} console.log(data,newData) // {} {a:1 , b:2, c:3}
方法二:
JSON.parse(JSON.stringify());let data = { a:1 , b:2 } const newData = JSON.parse(JSON.stringify(data)) data = {} console.log(data,newData) // {} {a:1 , b:2}
方法三:
引入loadsh的cloneDeep()方法实现深拷贝npm i --save lodash import _ from 'lodash' let data = { a:1 , b:2 } const newData = _.cloneDeep(data) data = {} console.log(data,newData) // {} {a:1 , b:2}
方法四:
jq的extend方法(需安装jq)/** * deep:深拷贝为true * objClone:生成的新对象 * obj:拷贝的对象 */ $.extend( deep, objClone, obj )