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 相关文章推荐
javascript应用:Iframe自适应其加载的内容高度
Apr 10 Javascript
Javascript学习笔记7 原型链的原理
Jan 11 Javascript
打印json对象的内容及JSON.stringify函数应用
Mar 29 Javascript
jQuery中index()方法用法实例
Dec 27 Javascript
Bootstrap 3.x打印预览背景色与文字显示异常的解决
Nov 06 Javascript
详解Jquery Easyui的验证扩展
Jan 09 Javascript
Extjs表单输入框异步校验的插件实现方法
Mar 20 Javascript
9种改善AngularJS性能的方法
Nov 28 Javascript
electron + vue项目实现打印小票功能及实现代码
Nov 25 Javascript
前端面试知识点目录一览
Apr 15 Javascript
vue中使用props传值的方法
May 08 Javascript
原生js实现针对Dom节点的CRUD操作示例
Aug 26 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操作xml入门之xml标签的属性分析
2015/01/23 PHP
php操作MongoDB类实例
2015/06/17 PHP
PHP基于cookie与session统计网站访问量并输出显示的方法
2016/01/15 PHP
HR vs CL BO3 第二场 2.13
2021/03/10 DOTA
JavaScript 基础问答三
2008/12/03 Javascript
javascript调试说明
2010/06/07 Javascript
jqTransform美化表单
2015/10/10 Javascript
Windows 系统下设置Nodejs NPM全局路径
2016/04/26 NodeJs
简单的jQuery拖拽排序效果的实现(增强动态)
2017/02/09 Javascript
通过js控制时间,一秒一秒自己动的实例
2017/10/25 Javascript
web前端vue filter 过滤器
2018/01/12 Javascript
关于axios不能使用Vue.use()浅析
2018/01/12 Javascript
浅析Vue.js 中的条件渲染指令
2018/11/19 Javascript
vue中$nextTick的用法讲解
2019/01/17 Javascript
vue 实现路由跳转时更改页面title
2019/11/05 Javascript
[07:43]《辉夜杯》公开赛晋级外卡赛战队—TRG训练生活探秘
2015/12/11 DOTA
初步认识Python中的列表与位运算符
2015/10/12 Python
Python实现简单的四则运算计算器
2016/11/02 Python
微信跳一跳python辅助软件思路及图像识别源码解析
2018/01/04 Python
pandas 实现字典转换成DataFrame的方法
2018/07/04 Python
如何优雅地改进Django中的模板碎片缓存详解
2018/07/04 Python
Flask实现图片的上传、下载及展示示例代码
2018/08/03 Python
Python API len函数操作过程解析
2020/03/05 Python
一款基于css3和jquery实现的动画显示弹出层按钮教程
2015/01/04 HTML / CSS
科颜氏英国官网:Kiehl’s英国
2019/11/20 全球购物
VC++笔试题
2014/10/13 面试题
应届生求职推荐信
2013/10/28 职场文书
优秀共产党员先进事迹
2014/01/27 职场文书
培训班开班仪式主持词
2014/03/28 职场文书
乡村文明行动实施方案
2014/03/29 职场文书
出租房屋协议书
2014/09/14 职场文书
死亡赔偿协议书
2015/01/28 职场文书
农村房屋租赁合同(范本)
2019/07/23 职场文书
JavaScript 数组去重详解
2021/09/15 Javascript
python程序的组织结构详解
2021/12/06 Python
浅谈JavaScript作用域
2021/12/06 Javascript