智能建站开发,品牌推广费用预算,网站开发 项目式说课,做旅游网站运营浅拷贝
浅拷贝 #xff1a; 浅拷贝是指对基本类型的值拷贝#xff0c;以及对对象类型的地址拷贝。它是将数据中所有的数据引用下来#xff0c;依旧指向同一个存放地址#xff0c;拷贝之后的数据修改之后#xff0c;也会影响到原数据的中的对象数据。最简单直接的浅拷贝就…浅拷贝
浅拷贝 浅拷贝是指对基本类型的值拷贝以及对对象类型的地址拷贝。它是将数据中所有的数据引用下来依旧指向同一个存放地址拷贝之后的数据修改之后也会影响到原数据的中的对象数据。最简单直接的浅拷贝就是直接赋值,如let obj xxx或者Array.prototype.slice()
深拷贝
深拷贝指复制并创建一个一模一样的对象不共享内存修改新对象旧对象保持不变。
应用场景常用的场景就是表格编辑对话框回显你需要深拷贝当前行数据赋值上去否则当你修改编辑框的数据你会发现表格的对应行的数据也会跟着修改。
Object.assign()
//用法
let obj {a:a,b:b}
let newObj Object.assign({},obj) 用法很简单可以拷贝复杂类型。但是有限制首先它只能用于对象的拷贝其次它是只能深拷贝第一层第二层开始就是浅拷贝了(一深二浅),不能拷贝循环引用类型。
实验代码
let obj {date:new Date(),regexp:new RegExp(),err:new Error(),fn:(){console.log(222)},un:undefined,nan:NaN,c:{fn:new Date()}
}
// obj.aobj //循环引用类型不能拷贝报错大概意思是说要转为json格式
let arr Object.assign({},obj)
console.log(obj,obj)
console.log(arr,arr) 实验截图 拓展运算符
拓展运算符的功能很强大可以用于对象和数组可以拷贝对象和数组可以将数组转换为参数序列复制数组合并数组等。这里主要讲的拷贝功能其他功能读者有兴趣可以另行寻找文章了解。
//扩展运算符(…)用于取出参数对象中的所有可遍历属性拷贝到当前对象之中
let obj {a:a,b:b}
let arr [1,2,3]
let newObj {...obj}
let newArr [...arr] 用法也是很简单也可以拷贝复杂类型。但是也有限制。仅作为第一层是为深拷贝可以拷贝复杂类型,对于数组和对象都一样,对于第二层极其以后的值扩展运算符将不能对其进行打散扩展也不能对其进行深拷贝即拷贝后和拷贝前第二层中的对象或者数组仍然引用的是同一个地址其中一方改变另一方也跟着改变。
实验代码
//这里只贴上对于数组的操作对象的操作跟上面的差不多拓展运算符的拷贝也不能拷贝循环引用的数据
let arr [1,2,3,[2,3,[4]]]
let newArr [...arr]
console.log(arr,arr)
console.log(newArr,newArr) 实验截图 JSON.parse(JSON.stringify(obj))
这种方式是我在项目中用的最多的方法。但是局限性比前两个还多。它只适用于纯数据json对象的深度克隆。
//用法
let obj {a:a}
let json JSON.parse(JSON.stringify(obj)) 用法简单局限性很多目前我所了解的大概有这些
1.如果obj里面存在时间对象,JSON.parse(JSON.stringify(obj))之后时间对象变成了字符串。 2.如果obj里有RegExp、Error对象则序列化的结果将只得到空对象。 3.如果obj里有函数undefined则序列化的结果会把函数 undefined丢失。 4.如果obj里有NaN、Infinity和-Infinity则序列化的结果会变成null。 5.JSON.stringify()只能序列化对象的可枚举的自有属性。如果obj中的对象是有构造函数生成的 则使用JSON.parse(JSON.stringify(obj))深拷贝后会丢弃对象的constructor。 6.如果对象中存在循环引用的情况也无法正确实现深拷贝。
实验代码
//定义一个构造函数function Person(age){this.age age}let obj {date: new Date(),regexp: new RegExp(),err: new Error(),fn: () {console.log(222)},un: undefined,nan: NaN,c: {fn: new Date()},age:new Person(20)}obj.a obj //无法拷贝循环引用的数据,报错大概意思是说要转为json格式let json JSON.parse(JSON.stringify(obj))console.log(obj, obj)console.log(json, json) 实验截图 使用较为完整的深拷贝
Lodash
建议使用Lodash库这是一个很强大的库里面有各种各样的封装方法十分强大。
1.安装npm i lodash2.组件引入import _ from lodash3.使用const form _.cloneDeep(拷贝的对象) 使用JQ
通过jq的$.extend()实现深拷贝当extend内的第一个参数为true时实现的是深拷贝false是浅拷贝。
自定义方法
这里的方法是从网上搬运过来的我之前面试的时候就背这个个人觉得挺全面的
function deepClone(obj, cache new WeakMap()) {if (typeof obj ! object) return obj //普通类型直接返回if (obj null) return objif (cache.get(obj)) return cache.get(obj)//防止循环引用程序进入死循环if (obj instanceof Date) return new Date(obj)//返回时间格式if (obj instanceof RegExp) return new RegExp(obj)//返回正则if (typeof obj symbol) return Symbol(obj.description) // 处理 Symbol//找到所属原型上的constructor,所属原型上的constructor指向点前对象的构造函数let cloneObj new obj.constructor()// console.log(cloneObj)cache.set(obj, cloneObj)//缓存拷贝的对象用于处理循环引用的情况for (let key in obj) {//hasOwnProperty() 方法会返回一个布尔值指示对象自身属性中是否具有指定的属性也就是是否有指定的键。if (obj.hasOwnProperty(key)) {// console.log(key)cloneObj[key] deepClone(obj[key], cache)//递归拷贝}}return cloneObj}//测试const obj { name: Jack, address: { x: 100, y: 200 }, a: [1, 2, 3, 4], b: Symbol(22) }obj.a obj//循环引用会一直嵌套const newObj deepClone(obj)console.log(obj, obj)console.log(newObj, newObj) 总结学艺不精请多多担待写下这篇文章主要是为了记录自己的成长如果能顺便帮到你那笔者会很开心。如果有大佬有宝贵的意见可以指导将万分感谢(*︶)
最后
最近找到一个VUE的文档它将VUE的各个知识点进行了总结整理成了《Vue 开发必须知道的36个技巧》。内容比较详实对各个知识点的讲解也十分到位。 有需要的小伙伴可以点击下方卡片领取无偿分享