关于javascript:夯基础手撕原型原型链

作为从前端刀耕火种年代走过去的物种-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 // true
foo1.__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 // true
Object.__proto__ === Function.prototype // true

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

在ES标准外面,Function继承Function自身,Function.prototype继承Object.prototype

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

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

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理