我们知道 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 原型链?的更多相关文章

  1. 转自知乎大神----JS 的 new 到底是干什么的?

    大部分讲 new 的文章会从面向对象的思路讲起,但是我始终认为,在解释一个事物的时候,不应该引入另一个更复杂的事物. 今天我从「省代码」的角度来讲 new. --------------------- ...

  2. JS原型链

    JS作为发展了多年了对象语言,支持继承,和完全面向对象语言不同的是,JS依赖原型链来实现对象的继承. 首先JS的对象分两大类,函数对象和普通对象,每个对象均内置__proto__属性,在不人为赋值__ ...

  3. 深入理解JS原型链与继承

    我 觉得阅读精彩的文章是提升自己最快的方法,而且我发现人在不同阶段看待同样的东西都会有不同的收获,有一天你看到一本好书或者好的文章,请记得收藏起来, 隔断时间再去看看,我想应该会有很大的收获.其实今天 ...

  4. js 原型链和继承(转)

    在理解继承之前,需要知道 js 的三个东西: 什么是 JS 原型链 this 的值到底是什么 JS 的 new 到底是干什么的 1. 什么是 JS 原型链? 我们知道 JS 有对象,比如 var ob ...

  5. 简单粗暴地理解js原型链–js面向对象编程

    简单粗暴地理解js原型链–js面向对象编程 作者:茄果 链接:http://www.cnblogs.com/qieguo/archive/2016/05/03/5451626.html 原型链理解起来 ...

  6. 深入分析JS原型链以及为什么不能在原型链上使用对象

    在刚刚接触JS原型链的时候都会接触到一个熟悉的名词:prototype:如果你曾经深入过prototype,你会接触到另一个名词:__proto__(注意:两边各有两条下划线,不是一条).以下将会围绕 ...

  7. js原型链与继承(初体验)

    js原型链与继承是js中的重点,所以我们通过以下三个例子来进行详细的讲解. 首先定义一个对象obj,该对象的原型为obj._proto_,我们可以用ES5中的getPrototypeOf这一方法来查询 ...

  8. JS 原型链图形详解

    JS原型链 这篇文章是「深入ECMA-262-3」系列的一个概览和摘要.每个部分都包含了对应章节的链接,所以你可以阅读它们以便对其有更深的理解. 对象 ECMAScript做为一个高度抽象的面向对象语 ...

  9. 一张图看懂 JS 原型链

    JS 原型链,画了张图,终于理清楚各种关系有木有 写在最后: __proto__是每个对象都有的一个属性,而prototype是函数才会有的属性!!! function Person() { } 是函 ...

随机推荐

  1. 配置LNPM

    在 Ubuntu 系统中,可以使用 apt-get 命令来搭建 LNMP环境.这种方式较编译方式安装更加简便,因此选择使用该方式来搭建环境以供学习. 安装Nginx 使用 sudo apt-get i ...

  2. Asp.Net_优化

    ASP.NET: 一.返回多个数据集 检查你的访问数据库的代码,看是否存在着要返回多次的请求.每次往返降低了你的应用程序的每秒能够响应请求的次数.通过在单个数据库请求中返回多个结果集,可以减少与数据库 ...

  3. EVA索赔系统JAVA拦截例外站点

    控制面板->JAVA->JAVA控制面板->安全->添加以下例外站点: https://aftersales.i.daimler.com https://swdist.afte ...

  4. Scala基础(1)

    Scala基础语法 声明与定义: val,常量声明                       val  x:T(把x声明成一个类型为T的常量)  x是变量的名字,T是变量的类型          v ...

  5. "Regressing Robust and Discriminative 3D Morphable Models with a very Deep Neural Network" 解读

    简介:这是一篇17年的CVPR,作者提出使用现有的人脸识别深度神经网络Resnet101来得到一个具有鲁棒性的人脸模型. 原文链接:https://www.researchgate.net/publi ...

  6. webpack4-用之初体验,一起敲它十一遍

    众所周知,webpack进入第4个大版本已经有2个月的时间了,而且webpack团队升级更新的速度也是非常的惊人 在写下如下内容的时候webpack已经出到了4.6的版本了,剑指5.0应该是指日可待了 ...

  7. 原生和jquery 的 ajax

    form数据的序列化: $('#submit').click(function(){ $('#form').serialize(); //会根据input里面的name,把数据序列化成字符串:eg:n ...

  8. 常用校验码(奇偶校验码、海明校验码、CRC校验码)

    一.奇偶校验码 二.海明校验码 三.CRC校验码   计算机系统运行时,各个部之间要进行数据交换.交换的过程中,会有发生误码的可能(即0变成1或1变成0),由于计算机的储存是通过二进制代码来实现的的, ...

  9. week8:个人博客作业

    团队作业(5) 要求 在PM 带领下, 每个团队深入分析下面行业的App, 找到行业的Top 5 (从下面的三个备选中,任选一个行业即可) 英语学习/词典App 笔记App 旅游行业的手机App 选择 ...

  10. Django 图片上传、存储与显示

    参考博客:http://www.cognize.me/2016/05/09/djangopic 开始之前要先安装python图像处理库:pip install --use-wheel Pillow 一 ...