这里是修真院前端小课堂,每篇分享文从
【背景介绍】【知识剖析】【常见问题】【解决方案】【编码实战】【扩展思考】【更多讨论】【参考文献】
八个方面深度解析前端知识/技能,本篇分享的是:
【简述原型链是什么,有什么用处?若想访问一个对象的原型,应该使用什么方法?】
1.背景介绍
原型链是一种机制,指的是JavaScript每个对象包括原型对象都有一个内置的[[proto]]属性指向创建它的函数对象的原型对象,即prototype属性。
2.知识剖析
我们知道 JS 有对象,比如
var obj = { name: 'obj' }
我们可以对 obj 进行一些操作,包括
「读」属性
「新增」属性
「更新」属性
「删除」属性
下面我们主要来看一下「读」和「新增」属性。
为什么有 VALUEOF / TOSTRING 属性呢?
在我们没有对 obj 进行任何其他操作之前,发现 obj 已经有几个属性(方法)了
那么问题来了:valueOf / toString / constructor 是怎么来?我们并没有给 obj.valueOf 赋值呀。
要搞清楚 VALUEOF / TOSTRING / CONSTRUCTOR 是怎么来的,就要用到 CONSOLE.DIR 了。
我们发现 console.dir(obj) 打出来的结果是:
1. obj 本身有一个属性 name(这是我们给它加的)
2. obj 还有一个属性叫做 __proto__(它是一个对象)
3. obj.__proto__ 有很多属性,包括 valueOf、toString、constructor 等
4. obj.__proto__ 其实也有一个叫做 __proto__ 的属性(console.log 没有显示),值为 null
现在回到我们的问题:obj 为什么会拥有 valueOf / toString / constructor 这几个属性?
答案:
这跟 __proto__ 有关。
当我们「读取」 obj.toString 时,JS 引擎会做下面的事情:
1. 看看 obj 对象本身有没有 toString 属性。没有就走到下一步。
2. 看看 obj.__proto__ 对象有没有 toString 属性,发现 obj.__proto__ 有 toString 属性,于是找到了
所以 obj.toString 实际上就是第 2 步中找到的 obj.__proto__.toString。
可以想象,
3. 如果 obj.__proto__ 没有,那么浏览器会继续查看 obj.__proto__.__proto__
4. 如果 obj.__proto__.__proto__ 也没有,那么浏览器会继续查看 obj.__proto__.__proto__.proto__
5. 直到找到 toString 或者 __proto__ 为 null。
3.常见问题
访问对象原型的方法有哪些?
4.解决方法
获取实例对象obj的原型对象,有三种方法
1. obj.__proto__
2. obj.constructor.prototype
3. Object.getPrototypeOf(obj)
上面三种方法之中,前两种都不是很可靠。最新的ES6标准规定,__proto__属性只有浏览器才需要部署,其他环境可以不部署。而obj.constructor.prototype在手动改变原型对象时,可能会失效。
5.编码实战
6.扩展思考
原型链是如何产生的呢?
引自知乎【写代码的苏打饼】专栏的JavaScript 世界万物诞生记
7.参考文献
参考二:zhangjiahao8961:JavaScript原型及原型链详解
“我们相信人人都可以成为一个工程师,现在开始,找个师兄,带你入门,学习的路上不再迷茫。
这里是技能树.IT修真院:http://www.jnshu.com,初学者转行到互联网行业的聚集地。"
欢迎加IT交流群565734203与大家一起讨论交流