- let obj = Object.assign(targetObj, …sourceObj)
作用:将一个或多个源对象自身的可枚举属性与目标对象的属性合并
返回值:合并后的目标对象
var obj1 = {name: 'zyp1'}
var obj2 = {name: 'zyp2', age: 18}
var obj3 = {name: 'zyp'}
obj3 = Object.defineProperty(obj3, 'like', {
value: 'reading'
})
var obj4 = {}
var obj = Object.assign(obj4, obj1, obj2, obj3)
console.log(obj) //结果为{name: "zyp", age: 18}
console.log(obj4) //结果也为{name: "zyp", age: 18}
以上例子可以看出,后定义的’name’属性值覆盖了前面的’name’属性值,而不可枚举的’like’属性值在合并过程中并没有被添加进目标对象,同时目标对象obj4本身也会发生变化。
需要注意的是: Object.assign会合并’key‘为Symbol的属性,但是对于[[getter]]和[[setter]]访问器属性,不能直接用Object.assign进行合并,如果需要合并访问器属性,可以采用MDN中的方法
这里还要提一下的是,用扩展运算符也可以实现对象的合并:
var obj5 = {...obj1, ...obj2, ...obj3}
console.log(obj5) //结果为{name: "zyp", age: 18}
可以看到这里得到的结果与Object.assign得到的结果一样。
- let obj = Object.create(protoObj, [propertiesObj])
作用:创建新对象,在创建新对象的同时定义其原型对象(protoObj)以及一些新的属性(propertiesObj,新属性构成的对象,可选)
返回值:创建的新对象
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prortotype.sayName = function() {
alert(this.name)
}
function Worker(name, age) {
Person.call(this, name, age)
}
var worker = new Worker('zyp', 18)
console.log(worker)
得到的worker对象结果如下图:
这个符合我们的预期,通过构造函数实现继承的子类实例不会继承父类的原型属性,因此父类的sayName方法并没有被子类对象继承。
//子类继承父类的原型属性
Worker.prototype = Object.create(Person.prototype)
Worker.prototype.constructor = Worker
得到的结果如下:
这里实际上实现了寄生组合式继承的效果,既继承了实例属性,也继承了原型方法和属性。关于寄生组合式继承及其他几种继承实现,可以参见我的另外一篇文章:谈谈js中的继承
Object.create方法的第二个参数跟defineProperties方法的第二个参数形式一致,可以是一个或多个包含属性描述符的属性,且默认的enumerable/configurable/writable值均为false,value/get/set值均为undefined
参考:
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/create