JavaScript之原型链
何谓“链”
链表?链条?在 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.prototype
fn.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