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__的属性进行赋值操作,没有把原型链穿起来