何谓“链”
链表?链条?在 JavaScript 中都不是
JavaScript 中的每一个对象都有一个特殊的内置属性[[Prototype]]可以通过__proto__进行访问。他指向的是一个原型对象。当我们访问一个对象的某个属性的时候,如果对象本身没有这个属性,就会向其原型查找,如果找到了就停止,如果没找到则为undefined(未定义),比如当我们 new 一个对象,我们根本就没有定义 toString 方法呀,但是它就在那里,不在这个对象身上,在它的原型链上!
Function? Object? 你是谁?
先看一段代码
1 | console.log(Function.__proto__ === Object.__proto__) |
猜猜会输出什么
在 JavaScript 里面,万物皆对象,所以函数也是对象,它叫做函数对象,所以一个函数身上会有__proto__这个属性就不奇怪了。
然而,在学习的过程中,函数不仅仅有__proto__这个属性,还有另外一个属性prototype,这两个又有什么区别呢?
不妨假设现在有一个函数 fn ,它的定义如下
1 | function fn(){ |
fn.__proto__指向什么 ?
fn 是一个函数对象,他的__proto__指向他的原型,也就是Function.prototype,因为在 JavaScript 中所有的函数都是通过 Function 构造函数创建的, 所以他们的__proto__指向的是Function.prototypefn.prototype指向什么?fn.prototype是一个对象,包含了所有 fn 实例所将要继承的属性和方法。当我们使用 new fn()创建一个新的实例的时候,这个新的实例的__proto__都会指向fn.prototype,纳尼! fn 不是一个方法吗,怎么会有属性!方法也是对象,小子。
es6 的extends关键字就是基于这个实现的
所以也就不难理解为什么typeof fn.__proto__是function,而typeof fn.prototype是object了
再来看一个有趣的东西
1 | console.log(Function.__proto__ === Function.prototype) |
晕了哈哈哈哈,这是比较特殊的部分,他们都指向 Function 原型,记住就好了
原型链一图流
狠狠的推导,这张图无敌!
1 | function User(){}; |
true
false
true
true
true
false
true
false
true