原型链和继承的本质是链表
原型链和继承的本质是链表
写在前面
原型和原型链一直都是 JavaScript 中很重要的概念,理解它们有助于我们理解预定义引用类型间的关系以及 JavaScript 中对象继承的实现机制,下面是我对原型和原型链的理解和总结。
原型链 [[prototype]]
[[ prototype ]] 的意义:正常情况下访问对象属性的时候会触发 [[ get ]] 操作,第一步会检查对象本身是否有这个属性,如果对象本身没有,则会访问对象的 [[ prototype ]]
链
Javascript 的继承是什么?
继承意味着复制操作,JavaScript(默认)并不会复制对象属性。相反,JavaScript 会在两个对象之间创建一个关联,这样一个对象就可以通过委托访问另一个对象的属性和函数。
委托这个术语可以更加准确地描述 JavaScript 中对象的关联机制。
大多数情况下,我们把通过 new
的函数调用成为“构造函数调用”
而实际上,这只是 new
操作符的副作用 ——new
操作符将生成的实例的 [[ prototype ]]
指向函数的 prototype
,再因为 JS 中访问属性的 [[ get ]]
的遍历原型链的行为导致实例可以“访问”构造函数的属性
1 | let a = new Foo() |
JS 继承的本质是链表的遍历过程
我们来看一个例子
1 | function Super(){}; |
来看下他们之间的关系
他们的关系就好像一条链表,当我们访问实例对象 suber
上的属性时,就是在这条链表上进行遍历。
面向委托的设计
以下这段代码中,我们抛弃了传统的 new
、构造函数、原型这些带有迷惑性的行为。
进而使用对象委托的方式,直接把 b1 委托到 Bar,将 Bar 委托到 Foo,更贴近原型链的本质
通过比较可以看出,面向委托(对象关联)的代码显然更加简洁,因为这种代码只关注一件事:对象之间的关联关系。
1 | Foo = { |