我在写一篇图解prototype和__proto__的区别时,搜资料搜到了一个有意思的现象,下面这两个运算返回的结果是一样的:

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的构造器是它自身
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

至于prototype和__proto__的关系如何推导,可以参考我写的上一篇博客《三张图搞懂JavaScript的原型对象与原型链

一张图看懂Function和Object的关系及简述instanceof运算符的更多相关文章

  1. 一张图看懂ANSYS17.0 流体 新功能与改进

    一张图看懂ANSYS17.0 流体 新功能与改进   提交 我的留言 加载中 已留言   一张图看懂ANSYS17.0 流体 新功能与改进 原创2016-02-03ANSYS模拟在线模拟在线 模拟在线 ...

  2. 一张图看懂开源许可协议,开源许可证GPL、BSD、MIT、Mozilla、Apache和LGPL的区别

    一张图看懂开源许可协议,开源许可证GPL.BSD.MIT.Mozilla.Apache和LGPL的区别 首先借用有心人士的一张相当直观清晰的图来划分各种协议:开源许可证GPL.BSD.MIT.Mozi ...

  3. FUNMVP:几张图看懂区块链技术到底是什么?(转载)

    几张图看懂区块链技术到底是什么? 本文转载自:http://www.cnblogs.com/behindman/p/8873191.html “区块链”的概念可以说是异常火爆,好像互联网金融峰会上没人 ...

  4. 4张图看懂delphi 10生成ipa和在iPhone虚拟器上调试(教程)

    4张图看懂delphi 10生成ipa和在iPhone虚拟器上调试(教程) (2016-02-01 03:21:06) 转载▼ 标签: delphi ios delphi10 教程 编程 分类: 编程 ...

  5. 一张图看懂css的position里的relative和absolute的区别

    position有以下属性:static.inherit.fixed.absolute.relative前三个好理解好区分:static:是默认状态,没有定位,元素出现在正常的流中(忽略 top, b ...

  6. [转帖]两张图看懂GDT、GDTR、LDT、LDTR的关系

    两张图看懂GDT.GDTR.LDT.LDTR的关系 2018-06-09 18:13:53 Six_666A 阅读数 2044更多 分类专栏: 深入理解linux内核   转自:http://ju.o ...

  7. 一张图看懂Rxjava的原理

    前言 Rxjava是NetFlix出品的Java框架, 官方描述为 a library for composing asynchronous and event-based programs usin ...

  8. Nodejs学习笔记(三)——一张图看懂Nodejs建站

    前言:一条线,竖着放,如果做不到精进至深,那就旋转90°,至少也图个幅度宽广. 通俗解释上面的胡言乱语:还没学会爬,就学起走了?! 继上篇<Nodejs学习笔记(二)——Eclipse中运行调试 ...

  9. 一张图看懂360°全景和VR的区别

    2016年开始,Facebook.谷歌.腾讯.阿里等互联网巨头都已开始抢食VR(虚拟现实)这块的大蛋糕,虚拟现实发展速度惊人.在这样强势发展的背景下,一些产品也开始打着VR的幌子,挂着VR的噱头卖起来 ...

随机推荐

  1. UWP 剪贴板 Clipboard

    Clipboard使用Windows.ApplicationModel.DataTransfer.Clipboard 设置文本 DataPackage dataPackage = new DataPa ...

  2. 体验搜狐PaaS平台搜狐云景-自动调度(Autoscale)

    今天,收到一封「搜狐云景」送邀请码的邮件,价值 200 rmb,立马前往官网简单了解一下,这个玩意儿是搜狐公司云战略的一个产品,一个 PaaS 平台,简单了解了一下特性: 1.自由定制运行环境,这表示 ...

  3. 【SIKIA计划】_10_Unity5.1UI系统-UGUI笔记

    Canvas——TextEventSystem 事件系统 0.滚动文本列表(隐藏背景)/Scroll/maskimage[Scroll Rect][Mask]——text(拉伸到显示全部)Scroll ...

  4. elasticsearch(全文检索)的介绍和安装

    ElasticSearch是一个基于Lucene的搜索服务器.它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口.Elasticsearch是用Java开发的,并作为Apach ...

  5. 多个EXCEL文件合并成一个

    Python的numpy处理起来会比较方便,有空实现一下,这里是Excel内部代码的方式: 合并方法如下: 1.需要把多个excel表都放在同一个文件夹里面,并在这个文件夹里面新建一个excel.如图 ...

  6. C++指定位数小数输出

    关键词:头文件<iomanip>,指令setw(x),fixed,setprecision(x). setw()这个指令也可以配合setfill('')用于对齐输出,详情见另一篇博客htt ...

  7. 笨办法学Python - 习题4: Variables and Names

    1.习题 4: 变量(variable)和命名 学习目标:了解Python中变量的定义,学习定义简明易记的变量名 变量:变量是存储内存中的值,就是每定义一个变量就会在内存中开辟一个空间.基于变量的类型 ...

  8. java内存结构JVM——java内存模型JMM——java对象模型JOM

    JVM内存结构 Java代码是要运行在虚拟机上的,而虚拟机在执行Java程序的过程中会把所管理的内存划分为若干个不同的数据区域,这些区域都有各自的用途.其中有些区域随着虚拟机进程的启动而存在,而有些区 ...

  9. #1490 : Tree Restoration-(微软2017在线笔试)

    输入n m km个数,表示每层的节点个数接下来m行是每层的节点,节点顺序是从左往右的k个叶子节点k*k个矩阵,表示叶子节点之间的距离 输出:每个节点的父亲节点编号,root节点是0 题解:1.很明显, ...

  10. 关于php的array_diff和array_diff_assoc的使用总结

    关于php的array_diff和array_diff_assoc的使用总结 2015-11-07 17:01 184人阅读 评论(0) 收藏 举报  分类: php学习感想(1)  版权声明:本文为 ...