转自知乎大神---什么是 JS 原型链?
我们知道 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。
上面的过程,就是「读」属性的「搜索过程」。
而这个「搜索过程」,是连着由 __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 方法' }

总结:
「读」属性时会沿着原型链搜索。
「新增」属性时不会去看原型链(但是如果你给这个属性加了一些配置,则不一样,以后讲)。
转自知乎大神---什么是 JS 原型链?的更多相关文章
- 转自知乎大神----JS 的 new 到底是干什么的?
大部分讲 new 的文章会从面向对象的思路讲起,但是我始终认为,在解释一个事物的时候,不应该引入另一个更复杂的事物. 今天我从「省代码」的角度来讲 new. --------------------- ...
- JS原型链
JS作为发展了多年了对象语言,支持继承,和完全面向对象语言不同的是,JS依赖原型链来实现对象的继承. 首先JS的对象分两大类,函数对象和普通对象,每个对象均内置__proto__属性,在不人为赋值__ ...
- 深入理解JS原型链与继承
我 觉得阅读精彩的文章是提升自己最快的方法,而且我发现人在不同阶段看待同样的东西都会有不同的收获,有一天你看到一本好书或者好的文章,请记得收藏起来, 隔断时间再去看看,我想应该会有很大的收获.其实今天 ...
- js 原型链和继承(转)
在理解继承之前,需要知道 js 的三个东西: 什么是 JS 原型链 this 的值到底是什么 JS 的 new 到底是干什么的 1. 什么是 JS 原型链? 我们知道 JS 有对象,比如 var ob ...
- 简单粗暴地理解js原型链–js面向对象编程
简单粗暴地理解js原型链–js面向对象编程 作者:茄果 链接:http://www.cnblogs.com/qieguo/archive/2016/05/03/5451626.html 原型链理解起来 ...
- 深入分析JS原型链以及为什么不能在原型链上使用对象
在刚刚接触JS原型链的时候都会接触到一个熟悉的名词:prototype:如果你曾经深入过prototype,你会接触到另一个名词:__proto__(注意:两边各有两条下划线,不是一条).以下将会围绕 ...
- js原型链与继承(初体验)
js原型链与继承是js中的重点,所以我们通过以下三个例子来进行详细的讲解. 首先定义一个对象obj,该对象的原型为obj._proto_,我们可以用ES5中的getPrototypeOf这一方法来查询 ...
- JS 原型链图形详解
JS原型链 这篇文章是「深入ECMA-262-3」系列的一个概览和摘要.每个部分都包含了对应章节的链接,所以你可以阅读它们以便对其有更深的理解. 对象 ECMAScript做为一个高度抽象的面向对象语 ...
- 一张图看懂 JS 原型链
JS 原型链,画了张图,终于理清楚各种关系有木有 写在最后: __proto__是每个对象都有的一个属性,而prototype是函数才会有的属性!!! function Person() { } 是函 ...
随机推荐
- docker之容器数据持久化
1.挂载本地目录为容器的数据存放目录 [root@node03 ~]# docker run -itd --name web01 -v /container_data/web:/data ubuntu ...
- linux一切皆文件之块设备文件(四)
一.知识准备 1.在linux中,一切皆为文件,所有不同种类的类型都被抽象成文件(比如:块设备,socket套接字,pipe队列) 2.操作这些不同的类型就像操作文件一样,比如增删改查等 3.块设备是 ...
- [paper]MaskFusion: Real-Time Recognition, Tracking and Reconstruction of Multiple Moving Objects
Before 近期在调研关于RGBD在室内移动机器人下的语义导航的研究.目前帝国理工的Andrew Davison在这边有两个团队在研究,分别是Fusion++ 和 这篇 MaskFusion.这篇是 ...
- HAOI2017 新型城市化 二分图的最大独立集+最大流+强连通缩点
题目链接(洛谷):https://www.luogu.org/problemnew/show/P3731 题意概述:给出一张二分图,询问删掉哪些边之后可以使这张二分图的最大独立集变大.N<=10 ...
- foreach 当被循环的变量为空时 不进入循环
$a = []; foreach($a as $v){ echo 222; } //不会输出222 并且不会报错
- 《Linux内核分析》课程第三周学习总结
姓名:何伟钦 学号:20135223 ( *原创作品转载请注明出处*) ( 学习课程:<Linux内核分析>MOOC课程http://mooc.study.163.com/course/U ...
- ajax异步导致js方法顺序执行不了
js两个方法调用的顺序,有时候是这样的 f1(); f2(); 本来是先执行f1的,但是如果f1里面进行ajax异步 async:true,那么可能会先执行f2,如果想要顺序执行,那么就把异步设 ...
- 弟三周作业之VS2015
这周有个任务就是安装VS2015,然后进行简单的单元测试. 首先我上吴小勇同学给的MSDN官网(http://www.itellyou.cn/)下载VS2013, 然后装上后,在工具栏里,点击工具里的 ...
- 团队作业4——WBS练习
一.作业要求 对团队项目进行任务分解 要求所有人共同参与 队长列出需求 成员进行估计 队长领导大家达成共识 形成团队报告,发至团队博客 注意:分解的粒度最小不应超过6小时(即一个人在6小时以内能够完 ...
- 第十一周(11.24-12.01)----WBS功能分解
功能 子功能 二级子功能 预计花费时间(小时) 游戏基础功能 显示首界面 绘制产产品主logo及不同难度下的布局 4 游戏 难度选择(初级.中级.高级) 4 退出整个程序 1 放弃 ...