为什么将构造函数的prototype属性设置为null
并不会阻止从该函数创建的对象调用Object.prototype
上的方法,就像将原型设置为Object.create(null)
呢?
也就是说,为什么会这样:
function Foo(){}
Foo.prototype = null;
console.log(new Foo().toString); //outputs function toString() { [native code] } (or whatever)
function Foo(){}
Foo.prototype = Object.create(null);
console.log(new Foo().toString); //output undefined
答案 0 :(得分:25)
是,您的观察是正确的 - 使用new
运算符构建的函数总是在此案例Object.prototype
中有一个对象原型这确实不同于使用Object.create创建的函数。
可以看到在JavaScript所基于的ES5语言规范中完全指定的此行为。让我们看看这个。
new
:[[Construct]]
函数方法的 Quoting the specification指示如何使用new
运算符创建对象,我们可以看到指定了以下内容:
如果Type(proto)不是Object,则将obj的[[Prototype]]内部属性设置为标准内置Object原型对象,如15.2.4中所述。
Object.create
:另一方面,如果我们查看The spec for Object.create
,我们可以看到Object.create(o)
指定:
将obj的[[Prototype]]内部属性设置为O。
这意味着我们可以设置它,它还明确检查它是否为该算法中的null或Object(请执行按照规范的链接阅读它:)
因此,使用new Foo
调用的对象的原型是Object.prototype
而不是null
。如果没有Object.create
仅使用标准方法,则无法创建没有原型的对象。