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 相关文章推荐
jQuery结合Json提交数据到Webservice,并接收从Webservice返回的Json数据
Feb 18 Javascript
js操作IE浏览器弹出浏览文件夹可以返回目录路径
Jul 14 Javascript
jQuery增加自定义函数的方法
Jul 18 Javascript
jQuery animate()实现背景色渐变效果的处理方法【使用jQuery.color.js插件】
Mar 15 Javascript
EasyUI实现下拉框多选功能
Nov 07 Javascript
Vue使用vux-ui自定义表单验证遇到的问题及解决方法
May 10 Javascript
vue better scroll 无法滚动的解决方法
Jun 07 Javascript
javascript中一些奇葩的日期换算方法总结
Nov 14 Javascript
JS实现数组去重,显示重复元素及个数的方法示例
Jan 21 Javascript
JavaScript基于遍历操作实现对象深拷贝功能示例
Mar 05 Javascript
新手如何快速理解js异步编程
Jun 24 Javascript
用React Native制作一个简单的游戏引擎
May 27 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
Codeigniter操作数据库表的优化写法总结
2014/06/12 PHP
php随机取mysql记录方法小结
2014/12/27 PHP
Yii2-GridView 中让关联字段带搜索和排序功能示例
2017/01/21 PHP
给jQuery方法添加回调函数一款插件的应用
2013/01/21 Javascript
禁用页面部分JavaScript不是全部而是部分
2014/09/03 Javascript
JavaScript简单下拉菜单实例代码
2015/09/07 Javascript
轮播的简单实现方法
2016/07/28 Javascript
vue中mint-ui环境搭建详细介绍
2017/04/06 Javascript
vue快捷键与基础指令详解
2017/06/01 Javascript
JS移动端/H5同时选择多张图片上传并使用canvas压缩图片
2017/06/20 Javascript
详解nodejs实现本地上传图片并预览功能(express4.0+)
2017/06/28 NodeJs
一个简易的js图片轮播效果
2017/07/22 Javascript
Vue自定义事件(详解)
2017/08/19 Javascript
Vue中封装input组件的实例详解
2017/10/17 Javascript
基于datepicker定义自己的angular时间组件的示例
2018/03/14 Javascript
原生JS实现旋转轮播图+文字内容切换效果【附源码】
2018/09/29 Javascript
微信小程序swiper组件实现抖音翻页切换视频功能的实例代码
2020/06/24 Javascript
html中创建并调用vue组件的几种方法汇总
2020/11/17 Javascript
pygame学习笔记(6):完成一个简单的游戏
2015/04/15 Python
Python判断文件和文件夹是否存在的方法
2015/05/21 Python
python实现批量监控网站
2016/09/09 Python
Python编程之序列操作实例详解
2017/07/22 Python
Python实现改变与矩形橡胶的线条的颜色代码示例
2018/01/05 Python
Python openpyxl 遍历所有sheet 查找特定字符串的方法
2018/12/10 Python
python实现基于信息增益的决策树归纳
2018/12/18 Python
详解python:time模块用法
2019/03/25 Python
Python中新式类与经典类的区别详析
2019/07/10 Python
Django3中的自定义用户模型实例详解
2020/08/23 Python
详解用selenium来下载小姐姐图片并保存
2021/01/26 Python
Internet主要有哪些网络群组成
2015/12/24 面试题
恒华伟业笔试面试题
2015/02/26 面试题
会计毕业生自我鉴定
2013/11/04 职场文书
电子商务专业自我鉴定
2013/12/18 职场文书
说谎欺骗人检讨书300字
2014/11/18 职场文书
2015幼儿园新学期寄语
2015/02/27 职场文书
安全守法证明
2015/06/23 职场文书