Skip to the content.

Object.create() vs new Object()

Object.create(), es6创建对象的方式

语法:Object.create(proto, [propertiesObject])

// configurable, enumerable, writable 默认为false


## 区别

### 一、 创建对象的方式不同
- `new Object()` 通过构造函数来创建对象, 添加的属性是在自身实例下,修改的属性影响原始对象。
- `Object.create()` 可以理解为继承一个对象, 添加的属性是在原型下,修改的属性不影响原始对象。

````js
// new Object() 方式创建
var a = {  rep : 'apple' }
var b = new Object(a)
console.log(b) // {rep: "apple"}
console.log(b.__proto__) // {}
console.log(b.rep) // "apple"
b.name='John'
console.log(a.name) // "John"
console.log(a === b)   // true

// Object.create() 方式创建
var a = { rep: 'apple' }
var b = Object.create(a)
console.log(b)  // {}
console.log(b.__proto__) // {rep: "apple"}
console.log(b.rep) // "apple"
b.name='John'
console.log(a.name) // undefined

二、 创建对象属性的性质不同

Object.create() 用第二个参数来创建非空对象的属性描述符默认是为false,而构造函数或字面量方法创建的对象属性的描述符默认为true.可使用Object.getOwnPropertyDescriptors()验证

三、创建空对象时不同

当用构造函数或对象字面量方法创建空对象时,对象时有原型属性的,即有_proto_; 当用Object.create()方法创建空对象时,对象是没有原型属性的。

四、__proto__ 属性

创建的对象,属性和方法是添加在__proto__上的

var proto = {
    name: 'John',
    talk(){ }
};
var o = Object.create(proto);

console.log(o)
//    {}
//      __proto__:
//          name: "John"
//          talk: ƒ talk()

如果用构造函数实现,则需要设置prototype:

var People = function(){}
People.prototype.name = 'John'
People.prototype.talk = function() {}
var p = new People();

作用与 __proto__ 相同,用来设置一个对象的 prototype 对象,返回参数对象本身。它是 ES6 正式推荐的设置原型对象的方法。

var proto = {
    name: 'John',
    talk(){ }
};
var o = {age: 30}
Object.setPrototypeOf(o, proto);
console.log(o)
//    {}
//      age: 40
//      __proto__:
//          name: "John"
//          talk: ƒ talk()

读取一个对象的原型对象

Object.getPrototypeOf('foo') === String.prototype // true
Object.getPrototypeOf(true) === Boolean.prototype // true

五、 原型属性的继承

Object.assign 是不能拷贝到继承或原型上的属性和方法的

var o2 = Object.assign({}, o)
o2.name // undefined

为什么说推荐这个方法呢?因为Object.assign() 方法不能正确拷贝 get ,set 属性,只会拷贝getter返回的结果,而Object.getOwnPropertyDescriptors()可以返回正确的getter和setter