在JS中创建对象最常见的方式一般有两种:Object.create()new Object(){}(对象字面量创建)

再说区别之前我们先要明确一些相关的概念:
1、对象有属性__proto__,指向该对象的构造函数的原型对象
2、构造函数函数除了有属性__proto__,还有属性prototype__proto__指向构造这个函数的构造函数的原型对象,prototype指向该构造函数函数的原型对象

function item(){
    a = 123;
}
const item1 = {
    a : 1234
}
var o1 = Object.create(item)
var o2 = object.create(item1)
var n = new item()

首先最明显的不同就是,Object.create(proto,[propertiesObject])中的proto可以是个对象实例(如上面的item1)也可以为构造函数函数(如上面的item),甚至可以为null,用作新构造对象的原型对象。

new Object( constructor )只能传入构造函数

Object.create

在创建的对象上没有继承 Object.prototype 原型链上的属性或者方法,例如:toString(), hasOwnProperty()等方法

先看Object.create()的实质:

Object.create =  function (o) {
    var F = function () {};  //创建一个临时的构造函数
    F.prototype = o;         //将传进来的参数作为F的原型
    return new F();          //用这个临时的构造函数去new出一个实例,并返回这个实例
};

例子:

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
console.log(o2.__proto__)  //ƒ () { this.a = 2  }
console.log(o2.prototype)  //{a: 3, constructor: ƒ}
console.log(Base.prototype)  //{a: 3, constructor: ƒ}
console.log(o1)  //Base {a: 2}
console.log(o1.__proto__)  ////{a: 3, constructor: ƒ}

看起来很复杂,怎么一个实例还有prototype的???

图解:

Object.create

new

综上,他们俩比较明显的区别就是:new关键字创建的对象会保留原构造函数的属性,而用Object.create()创建的对象不会。

new

原生JS实现new的过程

/**
 * 
 * @param  fn 构造函数
 * @param  arg 传入的形参
 */
function _mynew(fn, ...args) {
    const t = typeof(fn)
    //判断fn是否为一个函数(先判断为函数再判断是否能被new的函数)
    if(t !== "function"){
        throw new TypeError('${t} must be a function')
    }
    //1. 新建一个对象
    let _this = Object.create(fn.prototype);  //由fn.prototype作为原型去新建一个对象
    //2. 将实例的__proto__指向构造函数的prototype
    Object.setPrototypeOf(_this, fn.prototype);
    //3. 设置实例的constructor
    _this.constructor = fn;
    //4. 通过apply构造函数来传参
    const result = fn.apply (_this,args);
    //5.返回值判断(return值如果为引用值,则改变为其本身)
    if(result&&(typeof result === "object"||typeof result === "function")){
        return result
    }
    return _this;
}

{}

{}是javascript对象字面量创建的形式,其本质和new Object()并无区别,默认都是继承了Object对象上的prototype