实例讲解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的多组处理, 仅展开一个区块的折叠效果
Jan 09 Javascript
jquery插件制作教程 txtHover
Aug 17 Javascript
jQuery如何跳转到另一个网页 就这么简单
Dec 28 Javascript
jquery实现刷新随机变化样式特效(tag标签样式)
Feb 03 Javascript
基于node.js实现微信支付退款功能
Dec 19 Javascript
Node层模拟实现multipart表单的文件上传示例
Jan 02 Javascript
浅谈js获取ModelAndView值的问题
Mar 28 Javascript
微信小程序异步API为Promise简化异步编程的操作方法
Aug 14 Javascript
详解React服务端渲染从入门到精通
Mar 28 Javascript
新手快速入门微信小程序组件库 iView Weapp
Jun 24 Javascript
vue中的循环对象属性和属性值用法
Sep 04 Javascript
Vue中使用Echarts仪表盘展示实时数据的实现
Nov 01 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
PHP限制页面只能在微信自带浏览器访问的代码
2014/01/15 PHP
php中Socket创建与监听实现方法
2015/01/05 PHP
简单谈谈PHP面向对象之标识对象
2017/06/27 PHP
JQuery UI DatePicker中z-index默认为1的解决办法
2010/09/28 Javascript
浅谈jquery回调函数callback的使用
2015/01/30 Javascript
js实现简单的验证码
2015/12/25 Javascript
jQuery内容折叠效果插件用法实例分析(附demo源码)
2016/04/28 Javascript
移动端H5开发 Turn.js实现很棒的翻书效果
2016/06/20 Javascript
仿百度换肤功能的简单实例代码
2016/07/11 Javascript
原生js实现ajax方法(超简单)
2016/09/20 Javascript
JavaScript正则表达式替换字符串中图片地址(img src)的方法
2017/01/13 Javascript
微信小程序 弹幕功能简单实例
2017/02/14 Javascript
bootstrap的工具提示实例代码
2017/05/17 Javascript
防止页面url缓存中ajax中post请求的处理方法
2017/10/10 Javascript
用WebStorm进行Angularjs 2开发(环境篇:Windows 10,Angular-cli方式)
2018/12/05 Javascript
JavaScript解析及序列化JSON的方法实例分析
2019/01/04 Javascript
微信小程序学习笔记之获取位置信息操作图文详解
2019/03/29 Javascript
Layui数据表格 前后端json数据接收的方法
2019/09/19 Javascript
[51:53]DOTA2-DPC中国联赛 正赛 RNG vs Dragon BO3 第二场 1月24日
2021/03/11 DOTA
Python创建文件和追加文件内容实例
2014/10/21 Python
Python自动连接ssh的方法
2015/03/07 Python
浅谈使用Python变量时要避免的3个错误
2017/10/30 Python
Python干货:分享Python绘制六种可视化图表
2018/08/27 Python
python: 自动安装缺失库文件的方法
2018/10/22 Python
如何基于Python Matplotlib实现网格动画
2020/07/20 Python
HTML 5.1来了 9月份正式发布 更新内容预览
2016/04/26 HTML / CSS
HTML5 weui使用笔记
2019/11/21 HTML / CSS
美国班级戒指、帽子和礼服、毕业产品、年鉴:Balfour
2018/11/01 全球购物
英国网上自行车商店:Tredz Bikes
2019/10/29 全球购物
计算s=f(f(-1.4))的值
2014/05/06 面试题
J2EE包括哪些技术
2016/11/25 面试题
电大学习个人自我评价范文
2013/10/04 职场文书
QA工程师岗位职责
2013/11/20 职场文书
tp5使用layui实现多个图片上传(带附件选择)的方法实例
2021/11/17 PHP
mysql 获取时间方式
2022/03/20 MySQL
MySQL外键约束(Foreign Key)案例详解
2022/06/28 MySQL