在JavaScript中有这样一种说法“万物皆对象”。除了原始值,其他的都是对象。在JavaScript对象是非常重要。今天汇总下对象常用的方法以及对象拷贝。
Object.assign(target,...sources):
用于将所有可枚举属性的值从一个或者多个源对象复制到目标对象,将返回目标对象,参数target是目标对象,参数sources是源对象。
var person = {};
var people = {
name: "tom",
age: 18,
}
var person1 = Object.assign(person, people)
console.log(person, person1)
// 这行代码的输出结果是{name: "tom", age: 18},{name: "tom", age: 18}
Object.create(proto,[propertiesObject]):
创建一个新对象,使用现有对象来提供新创建对象的__proto__。参数一是新创建对象的原型对象。参数二是可选参数,如果没有则表示undefined。返回一个新的独享,带着指定原型对象和属性。
// create方法;
var person = {
name: "tom",
age: 18
}
var people = Object.create(person);
console.log(people)
// 这行代码的输出结果是一个空对象这个空对象上只有__proto__,且这个__proto__上有age: 18和name: "tom"。
Object.defineProperties(obj,props):
直接在一个对象上定义新的属性或者修改现有属性并返回该对象。obj:在其上定义或者修改属性的对象。props:要定义其可枚举属性或者修改的属性描述符的对象,对象中存在的属性描述符主要有两中:数据描述符和访问器描述符。
var obj = {};
var obj1 = {
value: true,
writable: true
}
var obj2 = {
value: 'hello',
writable: false
}
Object.defineProperties(obj, { obj1, obj2 })
console.log(obj)
// 输出结果是: {obj1: true, obj2: "hello"}
Object.entries():
返回一个给定对象自身课枚举属性的键值对数组,其排列方式与使用for···in循环遍历该对象时返回的顺序一致(区别在于for···in循环枚举原型链中的属性)。
Object.freeze():
方法可以冻结一个对象,一个被冻结的对象再也不能被修改,冻结了一个对象则不能向这个对象添加新的属性,不能删除该对象以有属性的可枚举性、可配置性、可写性,以及不能修改已有属性的值,此外冻结一个对象后该对象的原型也不能被修改。返回和传入的参数相同的对象。
Object.fromEntries(iterable):
把键值对列表转换为一个对象。iterable:类似实现了可迭代协议Array或者Map或者其他对象的可迭代对象。返回一个包含提供的可迭代对象条目的对应属性的新对象。
Objection.is(value1,value2)
判断两个值是不是相同的值。两个参数是两个需要比较的值。返回一个布尔值表示是不是相同。
prototypeObj.isPrototypeOf():
用于测试一个对象是不是存在在另一个对象的原型链上。
object.toString():
返回一个表示该对象的字符串。
var arr = [1, 2, 3, 4]
var obj = {
name: "tom",
age: 18
}
console.log(arr.toString(), obj.toString());
// 输出结果是:1,2,3,4 [object Object]
上面是常见的对象的方法,参考链接
即将一个对象的值赋值给另一个对象,这种情况在JavaScript中是很常见的。对于对象拷贝分为深拷贝和浅拷贝:
在说拷贝之前我们要先了解堆和栈的概念:
一般来说深浅拷贝指的是引用类型。
引用类型是直接复制或者赋值的称为浅拷贝,对于浅拷贝来说两个对象相互之间的关联性太强。
var arr = [1, 2, 3];
var arr1 = arr;
arr1[3] = 4;
console.log(arr1, arr)
// 输出结果是:[1,2,3,4] [1,2,3,4]
如上面的代码,对象浅拷贝一个值发生变化,另外一个的值也会改变。但是很多的时候我们只希望拷贝一个类型的属性和方法。显然,上面的情况就是不行的,所以我们就要用到深拷贝了。
引用类型内部的值的复制与地址无关称为深拷贝。对于深拷贝来说我们要实现的是其中一个的属性发生改变另外一个的值不会改变。ES6有一个新增的属性
Object.assign(target,...sources)
可以帮我们实现我们的需求。
var obj1 = {
a: 1,
b: 2
};
var obj2 = {};
Object.assign(obj2, obj1);
obj2.a = 3;
console.log(obj1, obj2);
//输出结果是: {a:1,b:2} {a:3,b:2}
这样就实现了我们想要的效果,但是这种情况只能进行第一层的深拷贝,更深层次的拷贝还是传址的。
var obj1 = [{ a: 1, b: 2 }, 2, 3];
var obj2 = [];
Object.assign(obj2, obj1);
obj2[0].a = 3;
console.log(obj1, obj2);
// 输出的结果是:[{ a: 3, b: 2 }, 2, 3] 和 [{ a: 3, b: 2 }, 2, 3]
这种情况和我们想要还是不一样。对于第二层的拷贝还有方法以下就是实现的一种方式。
function deepCopy(obj)
if (Array.isArray(obj)) {
var newObj = [];
} else {
var newObj = {};
};
for (var i in obj) {
if (typeof obj[i] == "object") {
newObj[i] = deepCopy(obj[i])
} else {
newObj[i] = obj[i];
}
};
return newObj;
};
var arr = [[1], 2, 3];
var arr1 = deepCopy(arr);
arr1[0].push(2);
console.log(arr, arr1)
// 输出结果是:[[1], 2, 3] [[1,2], 2, 3]
这样就实现了深拷贝。还有一种简单的方式实现更深层次的深拷贝:
var obj = { a: [1, 2, 3] };
var obj1 = JSON.parse(JSON.stringify(obj));
obj1.a.push(4);
console.log(obj, obj1)
// 输出结果是: {a: [1, 2, 3]} {a:[1, 2, 3, 4]}
用以上两种方式就可以实现深拷贝了。