1. Object.assign()
Object.assign() 用于将所有可枚举属性的值从一个或多个源对象,复制到目标对象。
语法:Object.assign(obj, ...sources)
- obj:目标对象
- sources:源对象,可以是多个
- 返回目标对象
复制一个对象
const obj = { a: 1 }
const copy = Object.assign({}, obj)
console.log(copy); // { a: 1 }
合并对象
const obj1 = { a: 1, b: 2 }
const obj2 = { b: 3, c: 4 }
const obj3 = { c: 5, d: 6 }
const obj = Object.assign(obj1, obj2, obj3)
console.log(obj) // {a: 1, b: 3, c: 5, d: 6}
注:如果目标对象与源对象有同名属性,则后面的属性会覆盖前面的属性;如果多个源对象有同名的属性,则后面的源对象会覆盖前面的。
对象的深拷贝
通过 Object.assign() 我们可以很快的实现对象的复制,然而这只是一个浅拷贝,因为 Object.assign() 方法拷贝的是可枚举属性值,如果源对象的属性值是一个对象的引用,那么该方法也只会复制其引用。
// 浅拷贝
let o1 = {
a: 0,
b: { c: 0 }
}
const o2 = Object.assign({}, o1)
o1.b.c = 1
console.log(o2.c) // 1
那么,我们怎么实现一个对象的深拷贝呢?
如果不考虑保留内置类型,最快速的方法是通过JSON.stringify() 将该对象转换为 json 字符串表现形式,然后再将其解析回对象。
// 深拷贝:方法一
let obj1 = { a: 0 , b: { c: 0}}
let obj2 = JSON.parse(JSON.stringify(obj1))
obj1.a = 4
obj1.b.c = 4
console.log(obj1) // { a: 4, b: { c: 4}}
console.log(obj2) // { a: 0, b: { c: 0}}
还可以通过递归的方法实现深拷贝
// 深拷贝:方法二
const obj = {
name: 'andy',
age: 18,
info: {
gender: 'male',
schoole: 'NEWS'
},
color: ['pink', 'yellow']
}
function deepCopy(obj){
let o = {}
for(let k in obj) { // 此处的for...in方法可以使用Object.keys(obj).map(k =>{....}) 替换
// 1.获取属性值
var item = obj[k]; // 2.判断属性值属于哪种数据类型
if(item instanceof Array) { // 是否是数组
o[k] = []
deepCopy(o[k], item)
} else if(item instanceof Object) { // 是否是对象
o[k] = {}
deepCopy(o[k], item)
} else { // 简单数据类型
o[k] = item
}
} return o
}
const newObj = deepCopy(obj)
console.log(newObj)
此外,还可以通过structured clone结构化克隆算法,有兴趣的自行查阅。
2. Object.create() 创建一个新对象
语法:Object.create(proto)
- proto:新创建对象的原型对象
- 返回一个新对象
使用:
const person = {
isHuman: false,
printIntroduction: function() {
console.log(`My name is ${this.name}. Am I human? ${this.isHuman}`);
}
}
// Object.create() 方式创建对象
const me = Object.create(person)
console.log(me) // {}
me.name = 'Matthew' // "name" is a property set on "me", but not on "person"
me.isHuman = true // inherited properties can be overwritten
me.printIntroduction() // My name is Matthew. Am I human? true
console.log(me.__proto__ === person) //true
// 通过new Object()方式创建对象
const me = new Object(person)
console.log(me) // {isHuman: false, printIntroduction: ƒ}
me.name = 'Matthew'
me.isHuman = true
console.log(me) // {isHuman: true, name: "Matthew", printIntroduction: ƒ}
Object.create() 可以实现对象的继承,可以通过对象实例的 __proto__ 属性访问原型链上的属性。
new Object() 方法创建的对象,给对象原型添加属性和方法则需要通过构造函数或者类。
function Person(name, age){
this.name=name this.age=age
}
Person.prototype.sayHi = function(){
console.log(this.name)
}
let p = new Person('jack', 20)
console.log(p.sayHi()) // jack
console.log(p.__proto__ === Person.prototype) // true
3. Object.defineProperty()
Object.defineProperty() 添加或修改现有属性,并返回该对象。
语法:Object.defineProperty(obj, prop, description)
obj:必需。目标对象
prop:必需。需定义或修改的属性的名字
descriptor:必需。目标属性所拥有的特性,以对象形式{}书写。
- value:设置属性的值,默认为 undefined
- writable:值是否可以重写,true | false,默认为 false
- enumerable:目标属性是否可以被枚举,true | false,默认为 false
- configurable:目标属性是否可以被删除或是否可以再次修改特性,true | false,默认为 false
const obj = {
id: 1,
name: 'phone',
price: '$599'
}
Object.defineProperty(obj, 'num', {
value: 100,
enumerable: false
})
console.log(obj) // {id: 1, name: "phone", price: "$599", num: 100}
console.log(Object.keys(obj)) // ["id", "name", "price"]
4. Object.entires()
Object.entires() 遍历并返回该对象可枚举属性的键值对数组
语法:Object.entires(obj)
- 返回对象可枚举属性的键值对数组
const obj = {
a: 'apple',
b: 'bar'
}
console.log(Object.entries(obj)) // [ ['a', 'apple'], ['b', 'bar'] ]
for (const [key, value] of Object.entries(obj)) {
console.log(`${key}: ${value}`) //"a: somestring" "b: 42"
}
Object.entries(obj).forEach(([key, value]) => {
console.log(`${key}: ${value}`) // "a: somestring", "b: 42"
})
5. Object.keys()
Object.keys() 用于获取对象自身所有可枚举的属性
语法:Object.keys(obj)
- 效果类似于 for...in
- 返回一个由属性名组成的数组
const obj = {
id: 1,
name: 'phone',
price: '$599',
num: 100
}
const objKeys = Object.keys(obj);
console.log(objKeys) //['id', 'name', 'price', 'num']
const arr = ['a', 'b', 'c']
const arrKeys = Object.keys(arr)
console.log(arrKeys) //['0', '1', '2']
补充:如果只要获取对象的可枚举属性,可用Object.keys
或用for...in
循环(for...in
循环会得到对象自身的和继承的可枚举属性,可以使用 hasOwnProperty()
方法过滤掉)
6. Object.values()
Object.values() 获取对象自身所有可枚举的属性值
语法:Object.values(obj)
- 返回一个由属性值组成的数组
const obj = {
id: 1,
name: 'phone',
price: '$599',
num: 100
}
const objValues = Object.values(obj);
console.log(objValues); //[1, 'phone', '$599', '100']
附:对象的所有属性和方法
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。