theme: devui-blue
本文正在参加「金石计划 . 瓜分6万现金大奖」
浅拷贝
浅拷贝会创建一个新的对象,浅拷贝得到的对象有着原对象属性的一份精确拷贝,如果属性是基本数据类型,拷贝的就是基本数据类型的值,如果属性是引用类型,拷贝的就是内存地址,无论我们修改拷贝之后的对象或者是原对象共有的属性时,另一个对象也会受到改变
简而言之浅拷贝就是指拷贝一层,拷贝第一层的基本数据类型的值,以及第一层的引用类型地址。
如何实现浅拷贝
1、Object.assign()
对象身上的一个方法,可以接受无限个参数,将其中第一个参数作为基础,后面的所有参数,只要第一个参数存在这个键名,就将值的地址指向修改为后面出现的地址,如果不存在,则添加一个新的属性,地址为后出现的地址,以此往复。
// 简易版Object.assign()
Object.prototype.my_assign = function(obj,...args) {
if(obj == null) throw new TypeError('Cannot convert undefined or null to object'); // (目标对象不能为空,我们可以直接设置{}传递进去,但必须设置值)。
const arr = [...args]
for(let i = 0; i < arr.length; i++) {
for(let key in arr[i]) {
arr[i].hasOwnProperty(key) && (obj[key] = arr[i][key])
}
}
return obj
}
// Object.assign()实现浅拷贝:
let a = {
name: '寒月十九',
age: 20,
like: {
n1: 'coding',
n2: 'reading'
}
}
let b = Object.assign({},a )
2、解构
// Object.assign()实现浅拷贝:
let a = {
name: '寒月十九',
age: 20,
like: {
n1: 'coding',
n2: 'reading'
}
}
let b = {...a}
3、Array.prototype.concat()
4、Array.prototype.slice()
后两个方法就不过多展示了,聊完浅拷贝,我们来看看深拷贝。
深拷贝
深拷贝会拷贝所有属性,并拷贝属性指向的动态分配的内存。当对象和它所引用的对象一起拷贝时即发生深拷贝。深拷贝相比于浅拷贝速度较慢并且花销较大。拷贝前后两个对象互不影响。
如何实现深拷贝
JSON.parse() && JSON.stringify()
JSON.parse()方法用来解析 JSON 字符串,构造由字符串描述的 JavaScript 值或对象。
JSON.stringify()方法将一个 JavaScript 对象或值转换为 JSON 字符串
let a = {
name: '寒月十九',
age: 20,
like: {
n1: 'coding',
n2: 'reading'
}
}
let b = JSON.parse(JSON.stringify(a));
b.name = '十九';
b.like.n1 = 'basketball';
console.log(a);
我们可以看到当我们修改深拷贝得到的对象b中的两个属性,一个属性为基本数据类型,一个为引用类类型,但是原对象a不受影响,但是借助JSON对象有几个缺点,需要我们注意下。
1、会忽略undefined、Symbol、函数(不能序列化)
let obj = {
name: '寒月十九',
a: undefined,
b: Symbol('harvey'),
c: function() {}
}
let obj1 = JSON.parse(JSON.stringify(obj));
console.log(obj1);
2、不能拷贝循环引用的对象
3、拷贝new Date()转换结果不正确
可以将其转为时间戳,就可以实现拷贝。
4、无法处理正则
5、对象中含有NaN,Infinity会变成null
手撕拷贝
手撕浅拷贝
// 浅拷贝的实现原理(仿造Object.assign())
function shallowCopy(obj) {
if(typeof obj !== 'object') return
var newObj = obj instanceof Array ? [] : {}
let res = {}
for(let key in obj){
if(obj.hasOwnProperty(key)) { // 判断是不是对象的显示属性
res[key] = obj[key]
}
}
return res
}
代码测试:
手撕深拷贝
function deepCopy(obj) {
if(typeof obj !== 'object') return obj// 不是引用类型,不需要拷贝
let newobj = obj instanceof Array ? [] : {}
for(let key in obj) {
if(obj.hasOwnProperty(key)){
newobj[key] = typeof obj[key] === 'object' ? deepCopy(obj[key]) : obj[key]
}
}
return newobj
}
暂无评论内容