实例讲解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 相关文章推荐
JTrackBar水平拖动效果
Jul 15 Javascript
Array, Array Constructor, for in loop, typeof, instanceOf
Sep 13 Javascript
JQuery文本改变触发事件如聚焦事件、失焦事件
Jan 15 Javascript
使用jquery选择器如何获取父级元素、同级元素、子元素
May 14 Javascript
JS遍历数组和对象的区别及递归遍历对象、数组、属性的方法详解
Jun 14 Javascript
Bootstrap 下拉多选框插件Bootstrap Multiselect
Jan 22 Javascript
详解数组Array.sort()排序的方法
May 09 Javascript
jQuery选择器中的特殊符号处理方法
Sep 08 jQuery
React中上传图片到七牛的示例代码
Oct 10 Javascript
浅谈vue的几种绑定变量的值 防止其改变的方法
Mar 01 Javascript
js中Generator函数的深入讲解
Apr 07 Javascript
Vue实现导入Excel功能步骤详解
Jul 03 Vue.js
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
回首过去10年中最搞笑的10部动漫,哪一部让你节操尽碎?
2020/03/03 日漫
欧美媒体选出10年前最流行的17部动画
2017/01/18 日漫
用Apache反向代理设置对外的WWW和文件服务器
2006/10/09 PHP
php不用正则采集速度探究总结
2008/03/24 PHP
ThinkPHP之A方法实例讲解
2014/06/20 PHP
Fedora下安装php Redis扩展笔记
2014/09/03 PHP
php支付宝手机网页支付类实例
2015/03/04 PHP
php版微信支付api.mch.weixin.qq.com域名解析慢原因与解决方法
2016/10/12 PHP
JavaScipt基本教程之JavaScript语言的基础
2008/01/16 Javascript
JavaScript为对象原型prototype添加属性的两种方式
2010/08/01 Javascript
使用jQuery中的when实现多个AJAX请求对应单个回调的例子分享
2014/04/23 Javascript
让JavaScript和其它资源并发下载的方法
2014/10/16 Javascript
jQuery使用height()获取高度需要注意的地方
2014/12/13 Javascript
JQUERY实现网页右下角固定位置展开关闭特效的方法
2015/07/27 Javascript
41个Web开发者必须收藏的JavaScript实用技巧
2016/07/22 Javascript
微信小程序 textarea 详解及简单使用方法
2016/12/05 Javascript
Bootstrap缩略图的创建方法
2017/03/22 Javascript
Jquery+Ajax+xml实现中国地区选择三级联动菜单效果(推荐)
2017/06/09 jQuery
基于JavaScript实现报警器提示音效果
2017/10/27 Javascript
Swiper实现导航栏滚动效果
2020/10/16 Javascript
python中文编码问题小结
2014/09/28 Python
Python中每次处理一个字符的5种方法
2015/05/21 Python
浅谈机器学习需要的了解的十大算法
2017/12/15 Python
Python查看微信撤回消息代码
2018/06/07 Python
django 中使用DateTime常用的时间查询方式
2019/12/03 Python
AmazeUI 按钮交互的实现示例
2020/08/24 HTML / CSS
乌克兰数字设备、配件和智能技术的连锁商店:KTC
2020/08/18 全球购物
什么是smarty? Smarty的优点是什么?
2013/08/11 面试题
计算机求职自荐信范文
2014/04/19 职场文书
村级四风对照检查材料
2014/08/24 职场文书
员工趣味活动方案
2014/08/27 职场文书
事业单位年度考核个人总结
2015/02/12 职场文书
2016优秀青年志愿者事迹材料
2016/02/25 职场文书
关于企业的执行力标语大全
2020/01/06 职场文书
python - timeit 时间模块
2021/04/06 Python
Centos7中MySQL数据库使用mysqldump进行每日自动备份的编写
2021/08/02 MySQL