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的模仿新浪微博时间的组件
Oct 04 Javascript
jsp js鼠标移动到指定区域显示选项卡离开时隐藏示例
Jun 14 Javascript
模拟电子签章盖章效果的jQuery插件源码
Jun 24 Javascript
JavaScript1.6数组新特性介绍以及JQuery的几个工具方法
Dec 06 Javascript
JS烟花背景效果实现方法
Mar 03 Javascript
JavaScript AOP编程实例
Jun 16 Javascript
JavaScript地理位置信息API
Jun 11 Javascript
JS实现环形进度条(从0到100%)效果
Jul 05 Javascript
JS实现简单的浮动碰撞效果示例
Dec 28 Javascript
jquery中为什么能用$操作
Jun 18 jQuery
使用xampp将angular项目运行在web服务器的教程
Sep 16 Javascript
JS实现放大镜效果
Sep 21 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
一个简单的自动发送邮件系统(一)
2006/10/09 PHP
默默小谈PHP&MYSQL分页原理及实现
2007/01/02 PHP
PHP 数组遍历顺序理解
2009/09/09 PHP
php eval函数用法总结
2012/10/31 PHP
解析用PHP实现var_export的详细介绍
2013/06/20 PHP
浅析php创建者模式
2014/11/25 PHP
PHP实现过滤掉非汉字字符只保留中文字符
2015/06/04 PHP
avalon js实现仿微博拖动图片排序
2015/08/14 Javascript
利用Javascript实现BMI计算器
2016/08/16 Javascript
使用React实现轮播效果组件示例代码
2016/09/05 Javascript
JS 组件系列之BootstrapTable的treegrid功能
2017/06/16 Javascript
关于angularJs清除浏览器缓存的方法
2017/11/28 Javascript
jQuery序列化form表单数据为JSON对象的实现方法
2018/09/20 jQuery
详解webpack loader和plugin编写
2018/10/12 Javascript
layui 关闭open弹出框 刷新table表格页面的方法
2019/09/16 Javascript
在vue中created、mounted等方法使用小结
2020/07/21 Javascript
vue中利用three.js实现全景图的完整示例
2020/12/07 Vue.js
[02:46]2014DOTA2国际邀请赛 选手为你解读比赛MVP充满梦想
2014/07/09 DOTA
python中wx将图标显示在右下角的脚本代码
2013/03/08 Python
玩转python爬虫之cookie使用方法
2016/02/17 Python
Python3.6安装及引入Requests库的实现方法
2018/01/24 Python
django数据库migrate失败的解决方法解析
2018/02/08 Python
python实现从本地摄像头和网络摄像头截取图片功能
2019/07/11 Python
使用Python函数进行模块化的实现
2019/11/15 Python
基于Python中isfile函数和isdir函数使用详解
2019/11/29 Python
TFRecord文件查看包含的所有Features代码
2020/02/17 Python
Tarte Cosmetics官网:美国最受欢迎的化妆品公司之一
2017/08/24 全球购物
中国跨境电子商务网站:NewFrog
2018/03/10 全球购物
Notino罗马尼亚网站:购买香水和化妆品
2019/07/20 全球购物
会计毕业生自我鉴定
2013/11/04 职场文书
新春联欢会主持词
2014/03/24 职场文书
借款协议书
2014/04/12 职场文书
教师批评与自我批评总结
2014/10/16 职场文书
大学生助学金感谢信
2015/01/21 职场文书
表扬稿表扬信的格式及范文
2019/06/24 职场文书
sqlserver2017共享功能目录路径不可改的解决方法
2021/04/16 SQL Server