原型链是什么?
大概念题,答题思路为大概念化成小概念(分割),抽象化成具体(举例)。
我的答题思路如下:
哦,原型链涉及到的概念挺多的,我举例说明一下吧。
假设我们有一个普通对象 x={}
,这个 x
会有一个隐藏属性,叫做 __?????__
,这个属性会指向 Object.prototype
,即
此时,我们说 x 的原型
是 Object.prototype,或者说 Object.prototype 是 x 的原型。
而这个 __?????__
属性的唯一作用就是用来指向 x 的原型的。
如果没有 __?????__
属性,x 就不知道自己的原型是谁了。
为什么我用问号来表示?因为这样你不容易晕。
接下来我来说说原型链,我还是举例说明吧。
假设我们有一个数组对象 a=[]
,这个 a
也会有一个隐藏属性,叫做 __?????__
,这个属性会指向 Array.prototype
,即
此时,我们说 a 的原型是 Array.prototype
,跟上面的 x 一样。但又有一点不一样,那就是 Array.prototype 也有一个隐藏属性 __?????__
,指向 Object.prototype
,即
这样一来,a 就有两层原型:
a 的原型是 Array.prototype
a 的原型的原型是 Object.prototype
于是就通过隐藏属性 __?????__
形成了一个链条:
这就是原型链。
以上我对「原型链是什么」的回答。
怎么做:
看起来只要改写 x 的隐藏属性 __?????__
就可以改变 x 的原型(链)
但是这不是标准推荐的写法,为了设置 x.__?????___
,推荐的写法是
没错,JS 就是这么别扭。
解决了什么问题:
在没有 Class 的情况下实现「继承」。以 a ===> Array.prototype ===> Object.prototype
为例,我们说:
a 是 Array 的实例,a 拥有 Array.prototype 里的属性
Array 继承了 Object(注意专业术语的使用)
a 是 Object 的间接实例,a 拥有 Object.prototype 里的属性
这样一来,a 就既拥有 Array.prototype 里的属性,又拥有 Object.prototype 里的属性。
优点:
简单、优雅。
缺点:
跟 class 相比,不支持私有属性。
怎么解决缺点:
使用 class 呗。但 class 是 ES6 引入的,不被旧 IE 浏览器支持。
建议熟读这篇文章:
Last updated