「这是我参与2022首次更文挑战的第2天,活动详情查看:2022首次更文挑战」。
1.对象拷贝
1.1.直接赋值
直接赋值的拷贝只复制对象的引用,不复制对象真正的值,并且不管是改变非引用类型的属性值还是改变引用类型的属性值,都会改变原有对象属性的值,这种只是浅拷贝。
var obj1 = {a:1,b:2,c:{num:3}};
var obj2 = obj1
obj2.a = 111
obj2.c.num = 333
console.log(obj1)
console.log(obj2)
1.2.扩展运算符...
使用扩展运算符...拷贝对象,会将某个对象中所有可遍历的属性拷贝到另一个对象中,在我个人看来其本质是浅拷贝。如果改变的不是引用类型的属性值,那么只遍历一层,不会改变原有对象的值;如果改变的是引用类型的属性值,那么原有对象的值也会被改变。
var obj1 = {a:1,b:2,c:{num:3}};
var obj2 = {...obj1}
obj2.a = 111
obj2.c.num = 333
console.log(obj1)
console.log(obj2)
1.3.Object.assign()
Object.assign() 方法也能实现对象的拷贝,它的本质其实是浅拷贝,如果改变引用类型属性的值,原对象的值也会被改变,与扩展运算符...一样。
var obj1 = {a:1,b:2,c:{num:3}};
var obj2 = Object.assign({}, obj1);//第一个参数target必填
obj2.a = 111
obj2.c.num = 333
console.log(obj1)
console.log(obj2)
1.4.JSON方法
可以使用该方法实现对对象的拷贝,对于不管是改变非引用类型属性的值还是改变引用类型属性的值,虽然它都不会改变原有对象属性的值。
var obj1 = {a:1,b:2,c:{num:3}};
var obj2 = JSON.parse(JSON.stringify(obj1))
obj2.a = 111
obj2.c.num = 333
console.log(obj1)
console.log(obj2)
但当对象里面出现函数时就不适用了,函数不会被拷贝,所以在我个人看来它本质上还是浅拷贝。
var obj1 = {
a:1,
b:2,
c:{num:3},
d:function(arg){
console.log(4)
}
};
var obj2 = JSON.parse(JSON.stringify(obj1))
console.log(obj1)
console.log(obj2)
1.5.手写递归方法
通过自己手写递归方法可以实现对象的深拷贝,完美解决以上所有问题。
function deepCopy(obj){
var newObj = obj.constructor === Array ? [] : {}
//先判断是否是对象
if(typeof obj !== 'object'){//不是对象
return obj;
}else{//是对象
for (var i in obj) {
if(typeof obj[i] === 'object'){//再判断对象的属性是否为对象
newObj[i] = deepCopy(obj[i])
}else{
newObj[i] =obj[i]
}
}
}
return newObj//最终返回的值
}
var obj1 = {
a:1,
b:2,
c:{num:3},
d:function(arg){
console.log(4)
}
};
var obj2 = deepCopy(obj1)
obj2.a = 111
obj2.c.num = 333
console.log(obj1)
console.log(obj2)
1.6.使用第三方库
1.6.1.jQuery.extend
1. 如果只为$.extend()指定了一个参数,则意味着参数target被省略。此时,target就是jQuery对象本身。通过这种方式,我们可以为全局对象jQuery添加新的函数。
2. 如果多个对象具有相同的属性,则后者会覆盖前者的属性值。
深拷贝:
//$.extend( true, object1, object2 ); // 深度拷贝
var obj1 = {
a:1,
b:2,
c:{num:3},
d:function(arg){
console.log(4)
}
};
var obj2 = $.extend(true,{},obj1)
obj2.a = 111
obj2.c.num = 333
console.log(obj1)
console.log(obj2)
浅拷贝:
//$.extend( object1, object2 ); // 浅拷贝
var obj1 = {
a:1,
b:2,
c:{num:3},
d:function(arg){
console.log(4)
}
};
var obj2 = $.extend({},obj1)
obj2.a = 111
obj2.c.num = 333
console.log(obj1)
console.log(obj2)
1.6.2.lodash
具体看官方
var obj1 = {
a:1,
b:2,
c:{num:3},
d:function(arg){
console.log(4)
}
};
var obj2 = _.cloneDeep(obj1)//深拷贝
obj2.a = 111
obj2.c.num = 333
console.log(obj1)
console.log(obj2)
2.对象合并
2.1.扩展运算符...
可以将多个对象进行合并,并且自动去重,对于相同的属性,后面的会覆盖前面的
var obj1 = {a:1,b:2,c:3}
var obj2 = {c:4,d:5}
var obj3 = {...obj1,...obj2}
console.log(obj3)//{a:1,b:2,c:4,d:5}
2.2.Object.assign()
Object.assign() 方法用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象上。
注意:
如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性。
如果只有一个target(目标对象),Object.assign会直接返回该对象。
var obj1 = {a:1,b:2,c:3}
var obj2 = {c:4,d:5}
var obj3 = Object.assign(obj1,obj2)
console.log(obj3)//{a: 1, b: 2, c: 4, d: 5}
3.获取对象的所有属性及其长度
3.1.Object.keys()
使用Object.keys()方法将返回该对象的所有属性组成的数组
var object1 = {a:1,b:2,c:3}
var arr1 = Object.keys(object1)
var len1 = Object.keys(object1).length
console.log(arr1)//['a','b','c']
console.log(len1)//3
4.对象属性的删除与新增
4.1.新增属性
var object1 = {a:1,b:2,c:3}
object1.d = 4
console.log(object1) //{a:1,b:2,c:3,d:4}
4.2.delete删除属性
delete() 可以删除对象中的某个属性,并返回一个布尔值
var object1 = {a:1,b:2,c:3}
delete object1.a
console.log(object1)//{b:2,c:3}
5.动态更改对象的属性名
首先定义一个动态的属性名,然后在声明对象的时候,将该动态属性名也绑定进去,这样就可以随时修改该属性名称了。
var dynamicName = "ee"
var object1 = {a:1,b:2,c:3,[dynamicName]:4}
console.log(object1)//{a:1,b:2,c:3,ee:4}
6.遍历对象
6.1.for....in
使用for....in可直接遍历对象
var object1 = {a:1,b:2,c:3}
for(var index in object1){
console.log(index,object1[index])
}
//0 1
//1 2
//2 3
6.2.Object.keys
先使用Object.keys获取该对象的所有属性组成的数组,再遍历该数组并取值。
var object1 = {a:1,b:2,c:3}
var objKeyArr = Object.keys(object1)
objKeyArr.forEach(function(index,key){
console.log(index,objKeyArr[index],object1[key])
})
//0 a 1
//1 b 2
//2 c 3
7.获取对象的所有属性值
7.1.Object.values()
使用Object.values()方法将返回该对象的所有属性值组成的数组
var object1 = {a:1,b:2,c:3}
var valuesArr = Object.values(object1)
console.log(valuesArr)//['1','2','3']