什么是深浅拷贝就不解释了,一般情况下我们只需要浅拷贝来操作我们的对象,但是对象内还存在对象的话就需要深拷贝了。因为浅拷贝只拷贝指针,而深拷贝可以重新申请空间并将数据复制过来,我的理解就是无限浅拷贝(^_^
)
let a = {
age: 1
}
let b = a
a.age = 2
console.log(b.age) // 2
出现这种情况的原因很简单,因为变量b同时指向变量a的对象内存,改变a的同时b的获取内存对象也会发生改变
浅拷贝的实现
Object.assign
let a = {
age: 1
}
let b = Object.assign({}, a)
a.age = 2
console.log(b.age) // 1
展开运算符 ...
let a = {
age: 1
}
let b = { ...a }
a.age = 2
console.log(b.age) // 1
通常浅拷贝就能解决大部分问题了,但是当我们遇到如下情况就可能需要使用到深拷贝了
let a = {
age: 1,
jobs: {
first: 'FE'
}
}
let b = { ...a }
a.jobs.first = 'native'
console.log(b.jobs.first) // native
浅拷贝只解决了第一层的问题,如果接下去的值中还有对象的话,那么就又回到最开始的话题了,两者享有相同的地址。要解决这个问题,我们就得使用深拷贝了。
这个问题通常可以通过 JSON.parse(JSON.stringify(object)) 来解决。
let a = {
age: 1,
jobs: {
first: 'FE'
}
}
let b = JSON.parse(JSON.stringify(a))
a.jobs.first = 'native'
console.log(b.jobs.first) // FE
但是该方法也是有局限性的:
会忽略 undefined
会忽略 symbol
不能序列化函数
不能解决循环引用的对象
let a = {
age: undefined,
sex: Symbol('male'),
jobs: function() {},
name: 'lwj'
}
let b = JSON.parse(JSON.stringify(a))
console.log(b) // {name: "lwj"}
当然如果你会lodash一下就解决了
//写个方法
function deepClone(obj) {
function isObject(o) {
return (typeof o === 'object' || typeof o === 'function') && o !== null
}
if (!isObject(obj)) {
throw new Error('非对象')
}
let isArray = Array.isArray(obj)
let newObj = isArray ? [...obj] : { ...obj }
Reflect.ownKeys(newObj).forEach(key => {
newObj[key] = isObject(obj[key]) ? deepClone(obj[key]) : obj[key]
})
return newObj
}
let obj = {
a: [1, 2, 3],
b: {
c: 2,
d: 3
}
}
let newObj = deepClone(obj)
newObj.b.c = 1
console.log(obj.b.c) // 2
仔细看还是能看懂的哈
Reflect.ownKeys可以理解成Object.getOwnPropertyNames(target) concat(Object.getOwnPropertySymbols(target)、
还是看代码吧
var obj={}
Object.defineProperties(obj,{
values:{
value:10,
enumerable:false
}
})
console.log(Object.keys(obj))//[] 空数组
console.log(Reflect.ownKeys(obj))// values
JavaScript是一门面向对象的语言,对大部分人来说这只是一句口号,很多人都不理解这句话的涵义是什么,即:为什么称JavaScript是一门面向对象的语言。
JavaScript作为一门面向对象的语言,意味着我们不用全局定义函数去做操不同类型的值,数据类型本身可以定义方法(method)来使用值,例如,要对数组a中的元素进行排序,我们不必将a传入sort()函数,而是调用a的一个方法sort()。
//面向过程
function sort(arr){
... //将传入的数组进行排序
return newArr
}
var a = [2,1,3]
a = sort(a)
//--------------------------------------------
var a = [2,1,3]
a.sort() // [1,2,3]
网友评论