Object.create 与 new 的区别

对比 Object.create 和 new 创建对象的实现原理和使用差异

问题

Object.createnew 创建对象有什么区别?

解答

Object.create 的实现原理

Object.create 内部创建一个临时构造函数,将传入的对象设置为原型,然后返回新实例:

Object.create = function (o) {
    var F = function () {};
    F.prototype = o;
    return new F();
};

new 的执行过程

使用 new 创建实例时,会执行以下步骤:

var o1 = new Object();
o1.__proto__ = Base.prototype;
Base.call(o1);
  1. 创建新对象
  2. 设置原型链指向构造函数的 prototype
  3. 执行构造函数,绑定 this

主要区别

示例 1:访问实例属性

var Base = function () {
    this.a = 2
}
var o1 = new Base();
var o2 = Object.create(Base);

console.log(o1.a); // 2
console.log(o2.a); // undefined

new 会执行构造函数,实例可以访问构造函数内定义的属性;Object.create 不会执行构造函数,无法访问实例属性。

示例 2:原型属性

var Base = function () {
    this.a = 2
}
Base.prototype.a = 3;

var o1 = new Base();
var o2 = Object.create(Base);

console.log(o1.a); // 2(实例属性优先)
console.log(o2.a); // undefined(Base 函数本身没有 a 属性)

关键点

  • Object.create(obj) 创建一个新对象,原型指向 obj,不执行构造函数
  • new Constructor() 创建实例,原型指向 Constructor.prototype,会执行构造函数
  • Object.create 传入构造函数时,新对象的原型是函数本身,而非 Constructor.prototype
  • new 创建的实例可以访问构造函数内的属性,Object.create 不会执行构造函数初始化