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 相关文章推荐
accesskey 提交
Jun 26 Javascript
jQuery 学习第七课 扩展jQuery的功能 插件开发
May 17 Javascript
input按钮的事件处理大全
Dec 10 Javascript
有关于JS构造函数的重载和工厂方法
Apr 07 Javascript
如何高效率去掉js数组中的重复项
Apr 12 Javascript
动态加载JavaScript文件的两种方法
Apr 22 Javascript
JS实现的样式切换功能tableCSS实例
Dec 30 Javascript
微信小程序 基础组件与导航组件详细介绍
Feb 21 Javascript
js实现4个方向滚动的球
Mar 06 Javascript
AngularJS表单验证功能分析
May 26 Javascript
详解Angular2 之 结构型指令
Jun 21 Javascript
Vue.js的动态组件模板的实现
Nov 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实现163邮箱自动发送邮件
2016/03/29 PHP
php中文字符串截取多种方法汇总
2016/10/06 PHP
yii2安装详细流程
2018/05/23 PHP
php设计模式之正面模式实例分析【星际争霸游戏案例】
2020/03/24 PHP
php变量与字符串的增删改查操作示例
2020/05/07 PHP
tp5.1 框架join方法用法实例分析
2020/05/26 PHP
javascript中的几个运算符
2007/06/29 Javascript
Javascript 表单之间的数据传递代码
2008/12/04 Javascript
Javascript 去除数组的重复元素
2010/05/04 Javascript
Javascript中获取出错代码所在文件及行数的代码
2010/09/23 Javascript
IFrame跨域高度自适应实现代码
2012/08/16 Javascript
简单常用的幻灯片播放实现代码
2013/09/25 Javascript
jQuery增加自定义函数的方法
2015/07/18 Javascript
JS实现的模仿QQ头像资料卡显示与隐藏效果
2017/04/07 Javascript
基于AngularJS的简单使用详解
2017/09/10 Javascript
浅谈微信JS-SDK 微信分享接口开发(介绍版)
2018/08/15 Javascript
JavaScript实现密码强度实时验证
2020/03/18 Javascript
vue 函数调用加括号与不加括号的区别
2020/10/29 Javascript
详解Python操作RabbitMQ服务器消息队列的远程结果返回
2016/06/30 Python
python实现贪吃蛇游戏
2020/03/21 Python
浅谈Python_Openpyxl使用(最全总结)
2019/09/05 Python
Python爬虫爬取电影票房数据及图表展示操作示例
2020/03/27 Python
浅谈Python 函数式编程
2020/06/20 Python
python和node.js生成当前时间戳的示例
2020/09/29 Python
Python爬虫爬取有道实现翻译功能
2020/11/27 Python
python实现跨年表白神器--你值得拥有
2021/01/04 Python
CSS3之transition实现下划线的示例代码
2018/05/30 HTML / CSS
东方电视购物:东方CJ
2016/10/12 全球购物
门诊挂号室室长岗位职责
2013/11/27 职场文书
幼儿园亲子活动方案
2014/01/29 职场文书
户外亲子活动策划方案
2014/02/07 职场文书
民政局离婚协议书范本
2014/10/20 职场文书
水知道答案观后感
2015/06/08 职场文书
企业内部管理控制:银行存款控制制度范本
2020/01/10 职场文书
Python实现Hash算法
2022/03/18 Python
Redis 报错 error:NOAUTH Authentication required
2022/05/15 Redis