实例讲解JavaScript中instanceof运算符的用法


Posted in Javascript onJune 08, 2016

instanceof 运算符简介

在 JavaScript 中,判断一个变量的类型尝尝会用 typeof 运算符,在使用 typeof 运算符时采用引用类型存储值会出现一个问题,无论引用的是什么类型的对象,它都返回 “object”。ECMAScript 引入了另一个 Java 运算符 instanceof 来解决这个问题。instanceof 运算符与 typeof 运算符相似,用于识别正在处理的对象的类型。与 typeof 方法不同的是,instanceof 方法要求开发者明确地确认对象为某特定类型。例如:

清单 1. instanceof 示例

var oStringObject = new String("hello world"); 
 console.log(oStringObject instanceof String); // 输出 "true"

这段代码问的是“变量 oStringObject 是否为 String 对象的实例?”oStringObject 的确是 String 对象的实例,因此结果是”true”。尽管不像 typeof 方法那样灵活,但是在 typeof 方法返回 “object” 的情况下,instanceof 方法还是很有用的。

instanceof 运算符的常规用法:

通常来讲,使用 instanceof 就是判断一个实例是否属于某种类型。例如:

清单 2. instanceof 常规用法

// 判断 foo 是否是 Foo 类的实例
 function Foo(){} 
 var foo = new Foo(); 
 console.log(foo instanceof Foo)//true

另外,更重的一点是 instanceof 可以在继承关系中用来判断一个实例是否属于它的父类型。例如:

清单 3. instanceof 在继承中关系中的用法

// 判断 foo 是否是 Foo 类的实例 , 并且是否是其父类型的实例
 function Aoo(){} 
 function Foo(){} 
 Foo.prototype = new Aoo();//JavaScript 原型继承
 
 var foo = new Foo(); 
 console.log(foo instanceof Foo)//true 
 console.log(foo instanceof Aoo)//true

上面的代码中是判断了一层继承关系中的父类,在多层继承关系中,instanceof 运算符同样适用。

你真的了解 instanceof 操作符吗?

看了上面的代码示例,是不是觉得 instanceof 操作符很简单,下面来看点复杂的用法。

清单 4. instanceof 复杂用法

console.log(Object instanceof Object);//true 
 console.log(Function instanceof Function);//true 
 console.log(Number instanceof Number);//false 
 console.log(String instanceof String);//false 
 
 console.log(Function instanceof Object);//true 
 
 console.log(Foo instanceof Function);//true 
 console.log(Foo instanceof Foo);//false

看了上面的代码是不是又晕头转向了?为什么 Object 和 Function instanceof 自己等于 true,而其他类 instanceof 自己却又不等于 true 呢?如何解释?要想从根本上了解 instanceof 的奥秘,需要从两个方面着手:1,语言规范中是如何定义这个运算符的。2,JavaScript 原型继承机制。

清单 5. JavaScript instanceof 运算符代码

function instance_of(L, R) {//L 表示左表达式,R 表示右表达式
 var O = R.prototype;// 取 R 的显示原型
 L = L.__proto__;// 取 L 的隐式原型
 while (true) { 
 if (L === null) 
 return false; 
 if (O === L)// 这里重点:当 O 严格等于 L 时,返回 true 
 return true; 
 L = L.__proto__; 
 } 
 }

清单 6. Object instanceof Object

// 为了方便表述,首先区分左侧表达式和右侧表达式
 ObjectL = Object, ObjectR = Object; 
 // 下面根据规范逐步推演
 O = ObjectR.prototype = Object.prototype 
 L = ObjectL.__proto__ = Function.prototype 
 // 第一次判断
 O != L 
 // 循环查找 L 是否还有 __proto__ 
 L = Function.prototype.__proto__ = Object.prototype 
 // 第二次判断
 O == L 
 // 返回 true

清单 7. Function instanceof Function

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

清单 8. Foo instanceof Foo

// 为了方便表述,首先区分左侧表达式和右侧表达式
 FooL = Foo, FooR = Foo; 
 // 下面根据规范逐步推演
 O = FooR.prototype = Foo.prototype 
 L = FooL.__proto__ = Function.prototype 
 // 第一次判断
 O != L 
 // 循环再次查找 L 是否还有 __proto__ 
 L = Function.prototype.__proto__ = Object.prototype 
 // 第二次判断
 O != L 
 // 再次循环查找 L 是否还有 __proto__ 
 L = Object.prototype.__proto__ = null 
 // 第三次判断
 L == null 
 // 返回 false

简析 instanceof 在 Dojo 继承机制中的应用

在 JavaScript 中,是没有多重继承这个概念的,就像 Java 一样。但在 Dojo 中使用 declare 声明类时,是允许继承自多个类的。下面以 Dojo 1.6.1 为例。

清单 9. Dojo 中多重继承

dojo.declare("Aoo",null,{}); 
 dojo.declare("Boo",null,{}); 
 dojo.declare("Foo",[Aoo,Boo],{}); 
 
 var foo = new Foo(); 
 console.log(foo instanceof Aoo);//true 
 console.log(foo instanceof Boo);//false 
 
 console.log(foo.isInstanceOf(Aoo));//true 
 console.log(foo.isInstanceOf(Boo));//true

上面的示例中,Foo 同时继承自 Aoo 和 Boo,但当使用 instanceof 运算符来检查 foo 是否是 Boo 的实例时,返回的是 false。实际上,在 Dojo 的内部,Foo 仍然只继承自 Aoo,而通过 mixin 机制把 Boo 类中的方法和属性拷贝到 Foo 中,所以当用 instanceof 运算符来检查是否是 Boo 的实例时,会返回 false。所以 Dojo 为每个类的实例添加了一个新的方法叫 isInstanceOf,用这个方法来检查多重继承。

Javascript 相关文章推荐
优秀js开源框架-jQuery使用手册(1)
Mar 10 Javascript
Ext JS 4官方文档之三 -- 类体系概述与实践
Dec 16 Javascript
简单实例处理url特殊符号&处理(2种方法)
Apr 02 Javascript
js实现可兼容IE、FF、Chrome、Opera及Safari的音乐播放器
Feb 11 Javascript
javascript瀑布流布局实现方法详解
Feb 17 Javascript
详解如何使用Node.js编写命令工具——以vue-cli为例
Jun 29 Javascript
React如何将组件渲染到指定DOM节点详解
Sep 08 Javascript
浅析Angular19 自定义表单控件
Jan 31 Javascript
对angular 监控数据模型变化的事件方法$watch详解
Oct 09 Javascript
在node中使用jwt签发与验证token的方法
Apr 03 Javascript
vue实现在线预览pdf文件和下载(pdf.js)
Nov 26 Javascript
JS Web Flex弹性盒子模型代码实例
Mar 10 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
js定义类的几种方法(推荐)
Jun 08 #Javascript
JavaScript必知必会(七)js对象继承
Jun 08 #Javascript
You might like
在PHP3中实现SESSION的功能(二)
2006/10/09 PHP
需要使用php模板的朋友必看的很多个顶级PHP模板引擎比较分析
2008/05/26 PHP
php中简单的对称加密算法实现
2017/01/05 PHP
laravel 5.4中实现无限级分类的方法示例
2017/07/27 PHP
JQuery 文本框使用小结
2010/05/22 Javascript
jQuery的学习步骤
2011/02/23 Javascript
jQuery中事件对象e的事件冒泡用法示例介绍
2014/04/25 Javascript
分享jQuery封装好的一些常用操作
2016/07/28 Javascript
基于jQuery实现滚动切换效果
2016/12/02 Javascript
js+div+css下拉导航菜单完整代码分享
2016/12/28 Javascript
js实现数组去重方法及效率?Ρ? target=
2017/02/14 Javascript
Django+Vue.js搭建前后端分离项目的示例
2017/08/07 Javascript
bootstrap table实现双击可编辑、添加、删除行功能
2017/09/27 Javascript
使用js实现将后台传入的json数据放在前台显示
2018/08/06 Javascript
vue解决跨域问题(推荐)
2020/11/10 Javascript
node使用async_hooks模块进行请求追踪
2021/01/28 Javascript
[04:54]DOTA2 2017国际邀请赛:上届冠军WINGS采访短片
2017/08/09 DOTA
使用python和pygame绘制繁花曲线的方法
2018/02/24 Python
Python实现注册、登录小程序功能
2018/09/21 Python
Python 利用切片从列表中取出一部分使用的方法
2019/02/01 Python
Python os.access()用法实例
2019/02/18 Python
python mac下安装虚拟环境的图文教程
2019/04/12 Python
如何通过Python实现标签云算法
2019/07/02 Python
Python中的引用和拷贝实例解析
2019/11/14 Python
Python面向对象程序设计之类和对象、实例变量、类变量用法分析
2020/03/23 Python
python opencv实现直线检测并测出倾斜角度(附源码+注释)
2020/12/31 Python
HTML5 canvas实现雪花飘落特效
2016/03/08 HTML / CSS
Saks Fifth Avenue澳洲/亚太地区:萨克斯第五大道精品百货店
2019/06/09 全球购物
什么是静态路由?什么是动态路由?各自的特点是什么?
2015/09/16 面试题
写给女朋友的道歉信
2014/01/08 职场文书
应聘销售主管的求职信
2014/04/26 职场文书
义务教育学校标准化建设汇报材料
2014/08/16 职场文书
党的群众路线教育实践活动制度建设计划方案
2014/10/31 职场文书
2015年社区环境卫生工作总结
2015/04/21 职场文书
父亲去世追悼词
2015/06/23 职场文书
Python实现老照片修复之上色小技巧
2021/10/16 Python