先看以下代码,下面这两个运算返回的结果是一样的:

Function instanceof Object;//true
Object instanceof Function;//true
复制代码

这个是怎么一回事呢?要从运算符instanceof说起。

一、instanceof究竟是运算什么的?

我曾经简单理解instanceof只是检测一个对象是否是另个对象new出来的实例(例如var a = new Object(),a instanceof Object返回true),但实际instanceof的运算规则上比这个更复杂。

首先w3c上有官方解释(传送门,有兴趣的同学可以去看看),但是一如既往地让人无法一目了然地看懂……

知乎上有同学把这个解释翻译成人能读懂的语言(传送门),看起来似乎明白一些了:

//假设instanceof运算符左边是L,右边是R
L instanceof R
//instanceof运算时,通过判断L的原型链上是否存在R.prototype
L.__proto__.__proto__ ..... === R.prototype ?
复制代码

//如果存在返回true 否则返回false 注意:instanceof运算时会递归查找L的原型链,即L.proto.proto.proto.proto...直到找到了或者找到顶层为止。

所以一句话理解instanceof的运算规则为:

instanceof检测左侧的__proto__原型链上,是否存在右侧的prototype原型。

二、图解构造器Function和Object的关系

图解构造器Function和Object的关系

我们再配合代码来看一下就明白了:

//①构造器Function的构造器是它自身
Function.constructor=== Function;//true//②构造器Object的构造器是Function(由此可知所有构造器的constructor都指向Function)
Object.constructor === Function;//true//③构造器Function的__proto__是一个特殊的匿名函数function() {}
console.log(Function.__proto__);//function() {}//④这个特殊的匿名函数的__proto__指向Object的prototype原型。
Function.__proto__.__proto__ === Object.prototype//true//⑤Object的__proto__指向Function的prototype,也就是上面③中所述的特殊匿名函数
Object.__proto__ === Function.prototype;//true
Function.prototype === Function.__proto__;//true
复制代码

三、当构造器Object和Function遇到instanceof

我们回过头来看第一部分那个“奇怪的现象”,从上面那个图中我们可以看到:

Function.__proto__.__proto__ === Object.prototype;//true
Object.__proto__ === Function.prototype;//true
复制代码

所以再看回第一点中我们说的instanceof的运算规则,Function instanceof Object 和 Object instanceof Function运算的结果当然都是true啦!

如果看完以上,你还觉得上面的关系看晕了的话,只需要记住下面几个最重要的关系,其他关系就可以推导出来了:

  1. 所有的构造器的constructor都指向Function

  2. Function的prototype指向一个特殊匿名函数,而这个特殊匿名函数的__proto__指向Object.prototype

  3. 原型链顶端是Object.prototype

  4. 构造函数创建的对象(Object、Function、Array、普通对象等)都是Function的实例,它们的__proto__均指向Function.prototype

  5. 除了Object,所有对象(或叫构造函数)的prototype,均继承自Object.prototype

转载于:https://juejin.im/post/5ccffb48f265da03a85ad45c

对于原型链的彻底理解相关推荐

  1. JS原型链的一些理解

    关于原型链我的理解是一个构造函数的原型作为另一个构造函数的实例形成的继承关系 在JS高级程序设计中有这样一个图 当我们定义一个函数时会有一个原型,即图中的SuperType Prototype,这时原 ...

  2. 《js中原型和原型链的深入理解》的笔记

    前言:在微信公众号前端大全上看过<js中原型和原型链的深入理解>,个人认为这是我看过的js原型链的文章中,在思维结构上理解最清楚的一个文章了,本着温故而知新,有害怕找不到这个文章,我就把文 ...

  3. JS中的原型链(超清晰理解)

    什么是原型链 原型链,所有的原型构成了一个链条,这个链条我们称之为原型链(prototype chain). 原型链的案例 如果我们执行下面这段代码,因为没有定义address这个属性,程序结果理所当 ...

  4. 原型与原型链的简单理解

    javascript的原型链有显式和隐式两种: 显式原型链:即我们常见的prototype: 隐式原型链:在一般环境下无法访问,即不可见,在FireFox下可以通过__proto__方式访问:隐式原型 ...

  5. 原型与原型链的学习理解

    目录 1.对象和函数的原型 1.1认识对象的原型 1.2函数的原型 1.3 将方法放到原型上 1.4总结: 1.5思考: 2.显式原型的属性 2.1默认属性 2.2重写原型对象 3.面向对象的特性-- ...

  6. 原型与原型链的个人理解

    一.原型是什么 什么是原型对象 每个函数都有一个prototype(原型)属性,这个属性都有一个指针,指向一个对象,这个对象可以让所有对象实例共享原型包含的方法和属性(就是原型对象).利用原型是当前构 ...

  7. 原型与原型链的详细理解

    js中的对象分为两种:普通对象object和函数对象function. function fn1(){};var fn2 = function(){};var fn3 = new Function() ...

  8. 我所理解的原型原型链

    一.题目 我们先看一道题目 var F = function() {}; Object.prototype.a = function() {console.log('a');};Function.pr ...

  9. 我所理解的原型原型链 1

    一.题目 我们先看一道题目 var F = function() {}; Object.prototype.a = function() {console.log('a');};Function.pr ...

最新文章

  1. Python基本语法_强制数据类型转换
  2. 周日21点50:关注电子阅读的大潮到来
  3. OpenCV2.4.4中调用SIFT特征检测器进行图像匹配
  4. 导师眼中让人崩溃的学生是什么样子的?
  5. IIS_FastCGI+php5.3+wincache+memcached+ZendLoader
  6. wpf文本框限制输入长度_Excel办公实操,限制输入日期,手机号码,不重复数据的使用...
  7. 软考备战系列一----软件测试基础
  8. python中import文件_Python导入其他文件中的.py文件 即模块
  9. 视频压缩工具linux,Ubuntu视频转换工具-mencoder命令行参数
  10. wireshark in text mode: tshark
  11. bootstrap学习笔记(1)基础段落,表格的实现
  12. 雷蛇鼠标:单机偶尔变成双击
  13. 46岁微软:从盖茨缔造帝国到纳德拉复兴
  14. 微信公众号二次开发实现自动回复文字,图片,图文功能
  15. wireshark抓包后查看数据报时的过滤规则/过滤语法及举例说明
  16. [OHIF-Viewers]医疗数字阅片-医学影像-es6解构赋值-const{}=-let{}=
  17. 【cudaMemcpy】
  18. GE Proficy CIMPLICITY如何实现跨版本升级操作?
  19. SQLAlchemy Datetime 和 TIMESTAMP
  20. vivo X21使用AS“解析包错误”问题解决

热门文章

  1. input type=file美化
  2. 算法工程师常用Linux命令总结
  3. 机器人伪装成人类在 GitHub 上为开源项目修复 bug
  4. 移动端rem布局与高清屏幕适配
  5. postgresql 数据库基本操作
  6. PHP的php://input和$HTTP_RAW_POST_DATA 和$_POST的关系
  7. Python 基础---列表
  8. POJ 3348 Cows
  9. Q108:浅析PBRT-V3的代码结构
  10. 7-2 修理牧场 (25 分)