JS三大经典 | 原型链继承2018-09-28
1. 什么是 JS 原型链?
2. this 的值到底是什么?
3. JS 的 new 到底是干什么的?
这是 JS 里的三个经典概念,自学者必须学会,否则无法通过面试。
今天主要来说一说自己对JS原型链继承的理解。
我们知道 JS 有对象,比如
var obj = { name: 'obj' }
我们可以对 obj 进行一些操作,包括
「读」属性
「新增」属性
「更新」属性
「删除」属性
下面我们主要来看一下「读」和「新增」属性。
为什么有 valueOf / toString 属性呢?
在我们没有对 obj 进行任何其他操作之前,发现 obj 已经有几个属性(方法)了:
那么问题来了:valueOf / toString / constructor 是怎么来?我们并没有给 obj.valueOf 赋值呀。
要搞清楚 valueOf / toString / constructor 是怎么来的,就要用到 console.dir 了。
我们发现 console.dir(obj) 打出来的结果是:
obj 本身有一个属性 name(这是我们给它加的)
obj 还有一个属性叫做 proto(它是一个对象)
obj.proto 有很多属性,包括 valueOf、toString、constructor 等
obj.proto 其实也有一个叫做 proto 的属性(console.log 没有显示),值为 null
现在回到我们的问题:obj 为什么会拥有 valueOf / toString / constructor 这几个属性?
答案:
这跟 proto 有关。
当我们「读取」 obj.toString 时,JS 引擎会做下面的事情:
看看 obj 对象本身有没有 toString 属性。没有就走到下一步。
看看 obj.proto 对象有没有 toString 属性,发现 obj.proto 有 toString 属性,于是找到了
所以 obj.toString 实际上就是第 2 步中找到的 obj.proto.toString。
可以想象,如果 obj.proto 没有,那么浏览器会继续查看 obj.proto.proto
如果 obj.proto.proto 也没有,那么浏览器会继续查看 obj.proto.proto.proto__
直到找到 toString 或者 proto 为 null。
上面的过程,就是「读」属性的「搜索过程」。
而这个「搜索过程」,是连着由 proto 组成的链子一直走的。
这个链子,就叫做「原型链」。
共享原型链
现在我们有另一个对象
var obj2 = { name: 'obj2' }
如图:
那么 obj.toString 和 obj2.toString 其实是同一个东西,也就是 obj2.proto.toString。
这有什么意义呢?
如果我们改写 obj2.proto.toString,那么 obj.toString 其实也会变!
这样 obj 和 obj2 就是具有某些相同行为的对象,这就是意义所在。
差异化
如果我们想让 obj.toString 和 obj2.toString 的行为不同怎么做呢?
直接赋值就好了:
obj.toString = function(){ return '新的 toString 方法' }
总结:
「读」属性时会沿着原型链搜索。
「新增」属性时不会去看原型链(但是如果你给这个属性加了一些配置,则不一样,以后讲)。
作者:littleyu
链接:https://www.jianshu.com/p/73a817fc94e2
共同学习,写下你的评论
评论加载中...
作者其他优质文章