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 相关文章推荐
MSN消息提示类
Sep 05 Javascript
LBS blog sql注射漏洞[All version]-官方已有补丁
Aug 26 Javascript
Jquery实现仿新浪微博获取文本框能输入的字数代码
Feb 22 Javascript
框架页面高度自动刷新的Javascript脚本
Nov 01 Javascript
关于onchange事件在IE和FF下的表现及解决方法
Mar 08 Javascript
字段太多jquey快速清空表单内容方法
Aug 21 Javascript
angularJS 中$scope方法使用指南
Feb 09 Javascript
浅析JavaScript作用域链、执行上下文与闭包
Feb 01 Javascript
全面解析JavaScript中“&&”和“||”操作符(总结篇)
Jul 18 Javascript
走进AngularJs之过滤器(filter)详解
Feb 17 Javascript
js数字滑动时钟的简单实现(示例讲解)
Aug 14 Javascript
Vue 页面跳转不用router-link的实现代码
Apr 12 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 IF ELSE简化/三元一次式的使用
2011/08/22 PHP
php缩小png图片不损失透明色的解决方法
2013/12/25 PHP
在php和MySql中计算时间差的方法详解
2015/03/27 PHP
PHP Filter过滤器全面解析
2016/08/09 PHP
jQuery 位置函数offset,innerWidth,innerHeight,outerWidth,outerHeight,scrollTop,scrollLeft
2010/03/23 Javascript
jquery $.ajax相关用法分享
2012/03/16 Javascript
基于javascript实现判断移动终端浏览器版本信息
2014/12/09 Javascript
深入理解JavaScript系列(29):设计模式之装饰者模式详解
2015/03/03 Javascript
javascript实现Table间隔色以及选择高亮(和动态切换数据)的方法
2015/05/14 Javascript
jQuery实现ctrl+enter(回车)提交表单
2015/10/19 Javascript
基于javascript实现tab选项卡切换特效调试笔记
2016/03/30 Javascript
H5移动端适配 Flexible方案
2016/10/24 Javascript
jQuery 利用ztree实现树形表格的实例代码
2017/09/27 jQuery
Windows安装Node.js报错:2503、2502的解决方法
2017/10/25 Javascript
Vue中添加手机验证码组件功能操作方法
2017/12/07 Javascript
简单了解微信小程序的目录结构
2019/07/01 Javascript
JavaScript forEach中return失效问题解决方案
2020/06/01 Javascript
深入了解Vue.js 混入(mixins)
2020/07/23 Javascript
[03:10]2014DOTA2 TI马来劲旅Titan首战告捷目标只是8强
2014/07/10 DOTA
[45:14]Optic vs VP 2018国际邀请赛淘汰赛BO3 第二场 8.24
2018/08/25 DOTA
如何在Python函数执行前后增加额外的行为
2016/10/20 Python
Python 爬虫之超链接 url中含有中文出错及解决办法
2017/08/03 Python
python基础教程项目二之画幅好画
2018/04/02 Python
详解python如何在django中为用户模型添加自定义权限
2018/10/15 Python
Python实现淘宝秒杀功能的示例代码
2021/01/19 Python
CSS3 translate导致字体模糊的实例代码
2019/08/30 HTML / CSS
Christys’ Hats官网:英国帽子制造商
2018/11/28 全球购物
写好求职应聘自荐信的三部曲
2013/09/21 职场文书
出纳岗位职责范本
2013/12/01 职场文书
公司租车协议书
2015/01/29 职场文书
辩护词格式
2015/05/22 职场文书
HR必备:销售经理聘用合同范本
2019/08/21 职场文书
CSS预处理框架——Stylus
2021/04/21 HTML / CSS
OpenCV-Python实现图像平滑处理操作
2021/06/08 Python
《杜鹃的婚约》OP主题曲「凸凹」无字幕影像公开
2022/04/08 日漫
Go语言编译原理之源码调试
2022/08/05 Golang