我碰巧从You Don't Know JS: this & Object prototyping中学习原型,这是一本很好的书,可以理解设计的底层,澄清许多误解(这就是为什么我试图避免使用继承和instanceof之类的东西)。
但我和这里的人有同样的问题。有几个答案真的很有帮助,很有启发性。我也很乐意分享我的理解。
什么是原型?
JavaScript中的对象有一个内部属性,在规范中表示为[[Prototype]],它只是对另一个对象的引用。几乎所有对象在创建时都会被赋予这个属性的非空值。
如何获得一个对象的原型?
通过__proto__或Object.getPrototypeOf
var a = { name: "wendi" };
a.__proto__ === Object.prototype // true
Object.getPrototypeOf(a) === Object.prototype // true
function Foo() {};
var b = new Foo();
b.__proto__ === Foo.prototype
b.__proto__.__proto__ === Object.prototype
原型是什么?
原型是作为函数的特殊属性自动创建的对象,用于建立委托(继承)链,即原型链。
当我们创建一个函数a时,prototype会自动作为a上的一个特殊属性创建,并将上的函数代码保存为prototype上的构造函数。
function Foo() {};
Foo.prototype // Object {constructor: function}
Foo.prototype.constructor === Foo // true
我想把这个属性作为存储函数对象的属性(包括方法)的地方。这也是JS中的实用函数被定义为Array.prototype.forEach()、Function.prototype.bind()、Object.prototype.toString()的原因。
为什么要强调函数的性质?
{}.prototype // undefined;
(function(){}).prototype // Object {constructor: function}
// The example above shows object does not have the prototype property.
// But we have Object.prototype, which implies an interesting fact that
typeof Object === "function"
var obj = new Object();
Arary, Function, Objectare都是函数。我必须承认,这刷新了我对JS的印象。我知道函数是JS中的一等公民,但它似乎是建立在函数之上的。
__proto__和prototype有什么区别?
__proto__a引用作用于每个对象以引用其[[Prototype]]属性。
Prototype是作为函数的特殊属性自动创建的对象,用于存储函数对象的属性(包括方法)。
有了这两个,我们可以在脑海中绘制出原型链。如图所示:
function Foo() {}
var b = new Foo();
b.__proto__ === Foo.prototype // true
Foo.__proto__ === Function.prototype // true
Function.prototype.__proto__ === Object.prototype // true