作为从前端刀耕火种年代走过去的物种-js原型,原型链,我示意当初高程看了不下三五遍也没能真正消化他,emmmmmm......不说了,我辈当自强,一个字,就是干......

就从构造函数说起吧

几个基本概念

  1. constructor: 失常状况下它会指向对象的构造函数,但这个属性很易扭转,比方你通过字面量形式重写了构造函数的prototype

    function F (){}var f = new F()f.constructor === F // 当初指向正确-------------------------强势宰割------------ --------F.prototype = {.....}f.constructor === F // false 当初constructor指向变了,f.instanceof === F  // true  用instanceof判断更稳
    1. 对象都有__proto__属性,包含函数,但只有函数才有prototype属性,函数被定义时它就存在了

构造函数

function Foo () {    this.num = 0}console.dir(Foo)Foo.prototype.constructor === Foo // true

在打印的后果外面能够看到构造函数Foo领有prototype属性,外面蕴含的有constructor和__proto__属性。Foo的这个prototype属性便是它的原型对象,咱们能够看到函数领有一个prototype属性,生下来就领有的。另外要留神的是原型对象(即Foo.prototype)的constructor指向构造函数自身。

这里波及到new运算符的一个毛病,用构造函数生成的实例对象,无奈共享属性和办法,起初为了解决这个问题,js的设计者Brendan Eich(布兰登·艾克)为构造函数引入了prototype属性,须要共享的属性和办法能够放到prototype对象里,算是欠缺了js的“类”。

prototype, __proto__

Foo.prototype.add = function (x) {    this.num += x}console.dir(Foo)var foo1 = new Foo()console.log(foo1)

咱们给Foo的原型对象挂载一个add办法,并创立一个它的实例foo1

构造函数Foo的原型对象上变领有了add办法,同时,打印进去的foo1也有add办法,认真看,foo的__proto__属性和Foo的prototype貌似一样啊,验证一下

相等,这阐明了实例的__proto__它会指向构造函数的原型对象,foo1的构造函数也就是Foo,所以上面这两个是成立的。

foo1.constructor === Foo // truefoo1.__proto__ === foo1.constructor.prototype === Foo.prototype // true

当咱们拜访foo1.add()办法时,foo对象自身不具备add办法,但它通过proto向上找到了他原型对象,所以能应用add办法,那如果Foo的原型对象上没有add这个办法怎么办?Foo作为一个对象也会有它本人的__proto__属性,通过__proto__属性Foo能够拜访到他构造函数的原型对象,这种顺着__proto__层层向上查找的链条机制,就是原型链。 实例通过__proto__链接到它构造函数的原型对象,而Foo函数作为对象也会有它本人__proto__属性,始终往上。

如上图,相似这样,这个链条向上最终会指向Object的原型对象,在向上就是null

总结一下:prototype外面寄存了一些共享的办法,而js正是通过__proto__prototype实现了原型链,以及对象的继承

Function、Object关系

像平时的String,RegExp, Number等函数都是继承Function而来

咱们晓得Function属于对象,而Objcet也属于构造函数

Function.__proto__ === Object.prototype // trueObject.__proto__ === Function.prototype // true

那么谁是老大呢,这个问题太容易被绕了.

在ES标准外面,Function继承Function自身,Function.prototype继承Object.prototype
Function.__proto__ === Function.prototype // trueFunction.prototype.__proto__ === Object.prototype // true

所以下面是成立的,也就是说Function.__proto__和Function.prototype指向是雷同的,都指向了Object.prototype,食物链的最顶端就是它了。