做者:苏墨橘
连接:https://www.zhihu.com/question/34183746/answer/59043879
来源:知乎
著做权归做者全部。商业转载请联系做者得到受权,非商业转载请注明出处。
react
正好这段时间在从新看这部分,写一篇回答来梳理一下吧。web
__proto__(隐式原型)与prototype(显式原型)express
1. 是什么NOTE Function objects created using Function.prototype.bind do not have a prototype property or the [[Code]], [[FormalParameters]], and [[Scope]] internal properties. ----- ECMAScript Language Specification
隐式原型指向建立这个对象的函数(constructor)的prototype浏览器
2. 做用是什么ECMAScript does not use classes such as those in C++, Smalltalk, or Java. Instead objects may be created in various ways including via a literal notation or via constructors which create objects and then execute code that initialises all or part of them by assigning initial values to their properties. Each constructor is a function that has a property named “prototype” that is used to implement prototype-based inheritance and shared properties.Objects are created by using constructors in new expressions; for example, new Date(2009,11) creates a new Date object. ----ECMAScript Language Specification
Every object created by a constructor has an implicit reference (called the object’s prototype) to the value of its constructor’s “prototype” ----ECMAScript Language Specification
道格拉斯在2006年写了一篇文章,题为 Prototypal Inheritance In JavaScript。在这篇文章中,他介绍了一种实现继承的方法,这种方法并无使用严格意义上的构造函数。他的想法是借助原型能够基于已有的对象建立新对象,同时还不比所以建立自定义类型,为了达到这个目的,他给出了以下函数:
function object(o){ function F(){} F.prototype = o; return new F() } ----- 《JavaScript高级程序设计》P169
//如下是用于验证的伪代码 var f = new F(); //因而有 f.__proto__ === F.prototype //true //又由于 F.prototype === o;//true //因此 f.__proto__ === o;
所以由Object.create(o)建立出来的对象它的隐式原型指向o。好了,对象的建立方式分析完了,如今你应该可以判断一个对象的__proto__指向谁了。函数
好吧,仍是举一些一眼看过去比较疑惑的例子来巩固一下。ui
function Foo(){} var foo = new Foo() Foo.prototype.__proto__ === Object.prototype //true 理由同上
function Bar(){} //这时咱们想让Foo继承Bar Foo.prototype = new Bar() Foo.prototype.__proto__ === Bar.prototype //true
//咱们不想让Foo继承谁,可是咱们要本身从新定义Foo.prototype
Foo.prototype = { a:10, b:-10 } //这种方式就是用了对象字面量的方式来建立一个对象,根据前文所述 Foo.prototype.__proto__ === Object.prototype
注: 以上两种状况都等于彻底重写了Foo.prototype,因此Foo.prototype.constructor也跟着改变了,因而乎constructor这个属性和原来的构造函数Foo()也就切断了联系。spa
既然是构造函数那么它就是Function()的实例,所以也就指向Function.prototype,好比 Object.__proto__ === Function.prototypeprototype
4. instanceof//设 L instanceof R
//经过判断
L.__proto__.__proto__ ..... === R.prototype ?
//最终返回true or false
Function instanceof Object // true Object instanceof Function // true Function instanceof Function //true Object instanceof Object // true Number instanceof Number //false