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

5次阅读

共计 1981 个字符,预计需要花费 5 分钟才能阅读完成。

作为从前端刀耕火种年代走过去的物种 -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, 食物链的最顶端就是它了。

正文完
 0