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 相关文章推荐
IE8 下的Js错误HTML Parsing Error...
Aug 14 Javascript
js replace替换所有匹配的字符串
Feb 13 Javascript
jquery获取选中的文本和值的方法
Jul 08 Javascript
在HTML中插入JavaScript代码的示例
Jun 03 Javascript
JS实现的新浪微博大厅文字内容滚动效果代码
Nov 05 Javascript
javascript实现tab切换的两个实例
Nov 05 Javascript
基于HTML模板和JSON数据的JavaScript交互(移动端)
Apr 06 Javascript
jQuery EasyUI Tab 选项卡问题小结
Aug 16 Javascript
bootstrap响应式导航条模板使用详解(含下拉菜单,弹出框)
Nov 17 Javascript
在vue里面设置全局变量或数据的方法
Mar 09 Javascript
如何自动化部署项目?折腾服务器之旅~
Apr 16 Javascript
Vue Router history模式的配置方法及其原理
May 30 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 foreach循环使用详解与实例代码
2010/05/08 PHP
分享下PHP register_globals 值为on与off的理解
2013/09/26 PHP
PHP实现过滤掉非汉字字符只保留中文字符
2015/06/04 PHP
开启PHP Static 关键字之旅模式
2015/11/13 PHP
Zend Framework教程之连接数据库并执行增删查的方法(附demo源码下载)
2016/03/21 PHP
PHP提取字符串中的手机号正则表达式怎么写
2017/07/17 PHP
编辑浪子版表单验证类
2007/05/12 Javascript
使用jQuery.Qrcode插件在客户端动态生成二维码并添加自定义Logo
2016/09/01 Javascript
JavaScript中无法通过div.style.left获取值的解决方法
2017/02/19 Javascript
在bootstrap中实现轮播图实例代码
2017/06/11 Javascript
node使用Mongoose类库实现简单的增删改查
2018/11/08 Javascript
vue实现移动端悬浮窗效果
2018/12/01 Javascript
微信小程序导航栏滑动定位功能示例(实现CSS3的positionsticky效果)
2019/01/24 Javascript
解决vue安装less报错Failed to compile with 1 errors的问题
2020/10/22 Javascript
js正则表达式简单校验方法
2021/01/03 Javascript
python发布模块的步骤分享
2014/02/21 Python
python文件读写操作与linux shell变量命令交互执行的方法
2015/01/14 Python
Windows系统配置python脚本开机启动的3种方法分享
2015/03/10 Python
Django查找网站项目根目录和对正则表达式的支持
2015/07/15 Python
浅谈python 四种数值类型(int,long,float,complex)
2016/06/08 Python
基于PyQt4和PySide实现输入对话框效果
2019/02/27 Python
基于Python新建用户并产生随机密码过程解析
2019/10/08 Python
python用WxPython库实现无边框窗体和透明窗体实现方法详解
2020/02/21 Python
python实现将两个文件夹合并至另一个文件夹(制作数据集)
2020/04/03 Python
如何在Anaconda中打开python自带idle
2020/09/21 Python
如何利用CSS3制作3D效果文字具体实现样式
2013/05/02 HTML / CSS
Agoda台湾官网:国内外订房2折起
2018/03/20 全球购物
Discard Protocol抛弃协议的作用是什么
2015/10/10 面试题
儿科护士自我鉴定
2013/10/14 职场文书
弘扬民族精神演讲稿
2014/05/07 职场文书
教育实习指导教师评语
2014/12/31 职场文书
租车协议书
2015/01/27 职场文书
2015年行政工作总结范文
2015/04/09 职场文书
2016民族团结先进个人事迹材料
2016/02/26 职场文书
使用Python+OpenCV进行卡类型及16位卡号数字的OCR功能
2021/08/30 Python
Apache Hudi集成Spark SQL操作hide表
2022/03/31 Servers