JavaScript的instanceof运算符学习教程


Posted in Javascript onJune 08, 2016

语法

object instanceof constructor

参数
object:
要检测的对象.
constructor:
某个构造函数

描述:
instanceof 运算符用来检测 constructor.prototype 是否存在于参数 object 的原型链上。

// 定义构造函数
function C(){} 
function D(){} 

var o = new C();

// true,因为 Object.getPrototypeOf(o) === C.prototype
o instanceof C; 

// false,因为 D.prototype不在o的原型链上
o instanceof D; 

o instanceof Object; // true,因为Object.prototype.isPrototypeOf(o)返回true
C.prototype instanceof Object // true,同上

C.prototype = {};
var o2 = new C();

o2 instanceof C; // true

o instanceof C; // false,C.prototype指向了一个空对象,这个空对象不在o的原型链上.

D.prototype = new C(); // 继承
var o3 = new D();
o3 instanceof D; // true
o3 instanceof C; // true

需要注意的是,如果表达式 obj instanceof Foo 返回true,则并不意味着该表达式会永远返回ture,因为Foo.prototype属性的值有可能会改变,改变之后的值很有可能不存在于obj的原型链上,这时原表达式的值就会成为false。另外一种情况下,原表达式的值也会改变,就是改变对象obj的原型链的情况,虽然在目前的ES规范中,我们只能读取对象的原型而不能改变它,但借助于非标准的__proto__魔法属性,是可以实现的。比如执行obj.__proto__ = {}之后,obj instanceof Foo就会返回false了。

instanceof和多全局对象(多个frame或多个window之间的交互)

在浏览器中,我们的脚本可能需要在多个窗口之间进行交互。多个窗口意味着多个全局环境,不同的全局环境拥有不同的全局对象,从而拥有不同的内置类型构造函数。这可能会引发一些问题。比如,表达式 [] instanceof window.frames[0].Array 会返回false,因为 Array.prototype !== window.frames[0].Array.prototype,因此你必须使用 Array.isArray(myObj) 或者 Object.prototype.toString.call(myObj) === "[object Array]"来判断myObj是否是数组。

示例
instanceof的常规用法是判断a是否是b类型:

console.log(true instanceof Boolean); // false 
console.log(new Number(1) instanceof Number); // true

instanceof还能判断父类型:

function Father() {}
function Child() {}
Child.prototype = new Father();
var a = new Child();
console.log(a instanceof Child); // true
console.log(a instanceof Father); // true

Child构造函数继承自Father,实例a是Child构造的无疑,但是为何也是Father的实例呢?其实instanceof运算符的内核可以简单地用以下代码描述:

function check(a, b) {
 while(a.__proto__) {
  if(a.__proto__ === b.prototype)
   return true;
  a = a.__proto__;
 }
 return false;
}

function Foo() {}
console.log(Object instanceof Object === check(Object, Object)); // true 
console.log(Function instanceof Function === check(Function, Function)); // true 
console.log(Number instanceof Number === check(Number, Number)); // true 
console.log(String instanceof String === check(String, String)); // true 
console.log(Function instanceof Object === check(Function, Object)); // true 
console.log(Foo instanceof Function === check(Foo, Function)); // true 
console.log(Foo instanceof Foo === check(Foo, Foo)); // true

简单地说,a如果是b的实例,那么a肯定能使用b的prototype中定义的方法和属性,那么用代码表示就是a的原型链中有b.prototype取值相同的对象,于是顺着a的原型链一层层找就行了。

另外值得注意的是,String Number Boolean 以及Function等都是函数,而函数则是统一由Function构造而来的,so它们和任何单纯的函数一样,能用Function上的原型属性:

Function.prototype.a = 10;
console.log(String.a); // 10

最后来简单讲讲最开始的两道题吧。

// 为了方便表述,首先区分左侧表达式和右侧表达式
 FunctionL = Function, FunctionR = Function; 
 // 下面根据规范逐步推演
 O = FunctionR.prototype = Function.prototype 
 L = FunctionL.__proto__ = Function.prototype 
 // 第一次判断
 O == L 
 // 返回 true

// 为了方便表述,首先区分左侧表达式和右侧表达式
 StringL = String, StringR = String; 
 // 下面根据规范逐步推演
 O = StringR.prototype = String.prototype 
 L = StringL.__proto__ = Function.prototype 
 // 第一次判断
 O != L
 // 循环再次查找 L 是否还有 __proto__ 
 L = String.prototype.__proto__ = Object.prototype 
 // 第二次判断
 O != L 
 // 再次循环查找 L 是否还有 __proto__ 
 L = String.prototype.__proto__ = null 
 // 第三次判断
 L == null 
 // 返回 false
Javascript 相关文章推荐
分享JavaScript获取网页关闭与取消关闭的事件
Dec 13 Javascript
jquery实现checkbox 全选/全不选的通用写法
Feb 22 Javascript
javascript几个易错点记录
Nov 26 Javascript
javascript实现粘贴qq截图功能(clipboardData)
May 29 Javascript
jQuery属性选择器用法示例
Sep 09 Javascript
jQuery编写设置和获取颜色的插件
Jan 09 Javascript
AngularJS双向绑定和依赖反转实例详解
Apr 15 Javascript
jquery操作ul的一些操作笔记整理(干货)
Aug 31 jQuery
Angular6 Filter实现页面搜索的示例代码
Dec 02 Javascript
Vue $mount实战之实现消息弹窗组件
Apr 22 Javascript
解决vue bus.$emit触发第一次$on监听不到问题
Jul 28 Javascript
vue项目查看vue版本及cli版本的实现方式
Oct 24 Javascript
JavaScript中instanceof运算符的使用示例
Jun 08 #Javascript
实例讲解JavaScript中instanceof运算符的用法
Jun 08 #Javascript
js获取对象、数组的实际长度,元素实际个数的实现代码
Jun 08 #Javascript
JS & JQuery 动态添加 select option
Jun 08 #Javascript
Jquery ajax请求导出Excel表格的实现代码
Jun 08 #Javascript
浅谈几种常用的JS类定义方法
Jun 08 #Javascript
浅谈javascript中的constructor
Jun 08 #Javascript
You might like
php 数组的创建、调用和更新实现代码
2009/03/09 PHP
WordPress网站性能优化指南
2015/11/18 PHP
PHP从数组中删除元素的四种方法实例
2017/05/12 PHP
PHP依赖注入(DI)和控制反转(IoC)详解
2017/06/12 PHP
Jquery 模拟用户点击超链接或者按钮的方法
2013/10/25 Javascript
jquery根据name属性查找的小例子
2013/11/21 Javascript
jQuery中slideUp()方法用法分析
2014/12/24 Javascript
在WordPress中加入Google搜索功能的简单步骤讲解
2016/01/04 Javascript
辨析JavaScript中的Undefined类型与null类型
2016/05/26 Javascript
原生js实现倒计时功能(多种格式调用)
2017/01/12 Javascript
使用vue和datatables进行表格的服务器端分页实例代码
2017/06/07 Javascript
jQuery 表单序列化实例代码
2017/06/11 jQuery
nodejs更改项目端口号的方法
2018/05/13 NodeJs
JavaScript实现创建自定义对象的常用方式总结
2018/07/09 Javascript
vue 登录滑动验证实现代码
2018/08/24 Javascript
js对象数组和对象的使用实例详解
2019/08/27 Javascript
angula中使用iframe点击后不执行变更检测的问题
2020/05/10 Javascript
vue实现公共方法抽离
2020/07/31 Javascript
详细解读Python中解析XML数据的方法
2015/10/15 Python
使用实现XlsxWriter创建Excel文件并编辑
2018/05/04 Python
对TensorFlow中的variables_to_restore函数详解
2018/07/30 Python
Centos部署django服务nginx+uwsgi的方法
2019/01/02 Python
python多线程调用exit无法退出的解决方法
2019/02/18 Python
Python去除字符串前后空格的几种方法
2019/03/04 Python
python实现对象列表根据某个属性排序的方法详解
2019/06/11 Python
Python+OpenCV图像处理——实现直线检测
2020/10/23 Python
下述程序的作用是计算机数组中的最大元素值及其下标
2012/11/26 面试题
财务科科长岗位职责
2014/03/10 职场文书
2014小学生国庆65周年演讲稿
2014/09/21 职场文书
办公室主任四风问题对照检查材料思想汇报
2014/09/28 职场文书
2014年企业工会工作总结
2014/11/12 职场文书
2014年护理工作总结范文
2014/11/14 职场文书
五星级酒店前台接待岗位职责
2015/04/02 职场文书
2015年宣传工作总结
2015/04/08 职场文书
我的中国梦主题班会
2015/08/14 职场文书
Windows11插耳机没反应怎么办? win11耳机没声音的多种解决办法
2021/11/21 数码科技