JS深入基础之Object.create和new的区别

663 阅读2分钟

Object.create() 和 new的区别

Object.create(null) 他创建出来的空对象是没有原型的。也就是Object.prototype上的所有方法他都没有。 可以试试打印这个创建出来空对象的toString()方法,会抛出一个类型错误。

所以其实呢Object.create()是把他里面的参数当作输出对象的原型来使用的。

比如你只要

var obj = Object.create({})

// 就可以使用toString了

但是在这个例子里面obj的原型其实是{},这个原型里其实也是没有toString方法的,他其实是再往上找到了Object.prototype里的toString

那应该怎么改成输出结果像{}一样呢。也很简单。

Object.create(Object.prototype)   就可以了

那么new呢?

var obj = new Object()

是能打印出toString()

new关键后面跟随的是一个构造函数的名字。其中逻辑其实也不外乎是把要return 的示例和构造函数的原型关联起来。

等于说其实也就是做了 obj.__proto__ = Constructor.prototype

和Object.create的对比如下

假设有 构造函数 Constructor

那么 var obj = new Constructor() 相当于 var obj = Object.create(Constructor.prototype)

再往细里面的想一点。我们在模拟new时候应当是如何初始话那个要返回的对象?

我们考虑过new的实际实现。需要用到__proto__属性。但是

proto ,绝大部分浏览器都支持这个非标准的方法访问原型,然而它并不存在于 Person.prototype 中,实际上,它是来自于 Object.prototype ,与其说是一个属性,不如说是一个 getter/setter,当使用 obj.proto 时,可以理解成返回了 Object.getPrototypeOf(obj)。

所以说我们好几种方法能用在模仿new的使用里

var obj = Object.create(Constructor.prototype)

或者

var obj = Object.create(Object.prototype)
//把obj的原型重新设置
obj.__proto__ =Constructor.prototype

但不能是

var obj = Object.create(null)
//这里的__proto__只是个普通的属性罢了
obj.__proto__ =Constructor.prototype

不然等于说只是对一个普通的名叫__proto__的属性进行赋值操作,没有把原型链穿起来