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 相关文章推荐
onpropertypchange
Jul 01 Javascript
JS之小练习代码
Oct 12 Javascript
基于jQuery实现动态数字展示效果
Aug 12 Javascript
BootStrap的JS插件之轮播效果案例详解
May 16 Javascript
Jquery跨域获得Json的简单实例
May 18 Javascript
Bootstrap教程JS插件滚动监听学习笔记分享
May 18 Javascript
JS使用JSON作为参数实例分析
Jun 23 Javascript
Vue完整项目构建(进阶篇)
Feb 10 Javascript
element ui table 增加筛选的方法示例
Nov 02 Javascript
Vue+iview+webpack ie浏览器兼容简单处理
Sep 20 Javascript
JS实现简单省市二级联动
Nov 27 Javascript
通过javascript实现扫雷游戏代码实例
Feb 09 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中unset,array_splice删除数组中元素的区别
2014/07/28 PHP
微信第三方登录(原生)demo【必看篇】
2017/05/26 PHP
juqery 学习之五 文档处理 包裹、替换、删除、复制
2011/02/11 Javascript
js实现一个省市区三级联动选择框代码分享
2013/03/06 Javascript
jQuery实现id模糊查询的小例子
2013/03/19 Javascript
加随机数引入脚本不让浏览器读取缓存
2014/09/04 Javascript
JS实现模拟风力的雪花飘落效果
2015/05/13 Javascript
使用控制台破解百小度一个月只准改一次名字
2015/08/13 Javascript
jQuery toggle 代替方法
2016/03/22 Javascript
详解JavaScript中双等号引起的隐性类型转换
2016/05/30 Javascript
JS构造函数与原型prototype的区别介绍
2016/07/04 Javascript
在Docker快速部署Node.js应用的详细步骤
2016/09/02 Javascript
AngularJs+Bootstrap实现漂亮的计算器
2017/08/10 Javascript
五步轻松实现JavaScript HTML时钟效果
2020/03/25 Javascript
微信小程序使用input组件实现密码框功能【附源码下载】
2017/12/11 Javascript
Vuex 入门教程
2018/01/10 Javascript
jQuery中内容过滤器简单用法示例
2018/03/31 jQuery
使用Node搭建reactSSR服务端渲染架构
2018/08/30 Javascript
js图片查看器插件用法示例
2019/06/22 Javascript
vue内置组件component--通过is属性动态渲染组件操作
2020/07/28 Javascript
JavaScript中如何调用Java方法
2020/09/16 Javascript
[04:23]DOTA2上海特锦赛小组赛第一日 TOP10精彩集锦
2016/02/27 DOTA
[50:17]Newbee vs Serenity 2018国际邀请赛小组赛BO2 第二场 8.17
2018/08/18 DOTA
python实现udp数据报传输的方法
2014/09/26 Python
Python实现修改IE注册表功能示例
2018/05/10 Python
Python发展史及网络爬虫
2019/06/19 Python
python适合人工智能的理由和优势
2019/06/28 Python
Python在OpenCV里实现极坐标变换功能
2019/09/02 Python
Python如何基于Tesseract实现识别文字功能
2020/06/05 Python
10个顶级Python实用库推荐
2021/03/04 Python
基于 HTML5 的 WebGL 3D 版俄罗斯方块的示例代码
2018/05/28 HTML / CSS
美国孕妇装品牌:Destination Maternity
2018/02/04 全球购物
美国排名第一的泳池用品直接来源:In The Swim
2019/09/23 全球购物
优秀党支部书记事迹材料
2014/05/29 职场文书
参加招聘会后的感想
2015/08/10 职场文书
经典哲理警句:志不真则心不热,心不热则功不贤
2019/11/14 职场文书