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 相关文章推荐
关于文本限制字数的js代码
Apr 02 Javascript
JS实现图片翻书效果示例代码
Sep 09 Javascript
JavaScript模块随意拖动示例代码
May 27 Javascript
jquery图片轮播特效代码分享
Apr 20 Javascript
js+css绘制颜色动态变化的圈中圈效果
Jan 27 Javascript
在javascript中创建对象的各种模式解析
May 16 Javascript
Laydate时间组件在火狐浏览器下有多时间输入框时只能给第一个输入框赋值的解决方法
Aug 18 Javascript
AngularJS $injector 依赖注入详解
Sep 14 Javascript
Jq通过td获取同行其它列td的方法
Oct 05 Javascript
js轮播图透明度切换(带上下页和底部圆点切换)
Apr 27 Javascript
使用vuex的state状态对象的5种方式
Apr 19 Javascript
使用 JavaScript 制作页面效果
Apr 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
php中关于普通表单多文件上传的处理方法
2011/03/25 PHP
PHP strip_tags()去除HTML、XML以及PHP的标签介绍
2014/02/18 PHP
php7基于递归实现删除空文件夹的方法示例
2017/06/15 PHP
如何在PHP环境中使用ProtoBuf数据格式
2020/06/19 PHP
用JavaScript编写COM组件的步骤
2009/03/17 Javascript
JavaScript DOM 学习第七章 表单的扩展
2010/02/19 Javascript
悬浮广告方法日常收集整理
2016/03/18 Javascript
Easyui 之 Treegrid 笔记
2016/04/29 Javascript
javascript简单判断输入内容是否合法的方法
2016/05/11 Javascript
浅谈jquery页面初始化的4种方式
2016/11/27 Javascript
JS中关于正则的巧妙操作
2017/08/31 Javascript
对mac下nodejs 更新到最新版本的最新方法(推荐)
2018/05/17 NodeJs
浅谈手写node可读流之流动模式
2018/06/01 Javascript
jQuery实现网页拼图游戏
2020/04/22 jQuery
vue实现的上拉加载更多数据/分页功能示例
2019/05/25 Javascript
VUE UPLOAD 通过ACTION返回上传结果操作
2020/09/07 Javascript
Python求导数的方法
2015/05/09 Python
python 捕获 shell/bash 脚本的输出结果实例
2017/01/04 Python
Python装饰器用法实例分析
2019/01/14 Python
利用python list完成最简单的DB连接池方法
2019/08/09 Python
Python二次规划和线性规划使用实例
2019/12/09 Python
Python基于pyecharts实现关联图绘制
2020/03/27 Python
HTML5 transform三维立方体实现360无死角三维旋转效果
2014/08/22 HTML / CSS
基于HTML5的齿轮动画特效
2016/02/29 HTML / CSS
Chemist Warehouse官方海外旗舰店:澳洲第一连锁大药房
2017/08/25 全球购物
城市观光通行证:The Sightseeing Pass
2018/04/28 全球购物
会计专业毕业生自荐信范文
2013/12/20 职场文书
给老婆的搞笑检讨书
2014/01/12 职场文书
元旦晚会策划方案
2014/02/18 职场文书
大龄毕业生求职别忘职业规划
2014/03/11 职场文书
教师暑期培训感言
2014/08/15 职场文书
手术室护士节演讲稿
2014/08/27 职场文书
领导班子个人查摆问题对照检查材料
2014/10/02 职场文书
公司授权委托书
2014/10/17 职场文书
英语教师求职信范文
2015/03/20 职场文书
歌咏比赛口号大全
2015/12/25 职场文书