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获取DOM元素位置和尺寸大小的方法
Apr 12 Javascript
Javascript实现滚动图片新闻的实例代码
Nov 27 Javascript
jQuery获得document和window对象宽度和高度的方法
Mar 25 Javascript
php结合imgareaselect实现图片裁剪
Jul 05 Javascript
JS组件Bootstrap实现下拉菜单效果代码
Apr 26 Javascript
详解基于webpack2.x的vue2.x的多页面站点
Aug 21 Javascript
JavaScript复制内容到剪贴板的两种常用方法
Feb 27 Javascript
JS将时间秒转换成天小时分钟秒的字符串
Jul 10 Javascript
20道JS原理题助你面试一臂之力(必看)
Jul 22 Javascript
javascript-hashchange事件和历史状态管理实例分析
Apr 18 Javascript
Javascript前端下载后台传来的文件流代码实例
Aug 18 Javascript
微信小程序实现多张图片上传功能
Nov 18 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 array_slice函数的使用以及参数详解
2008/08/30 PHP
php采集时被封ip的解决方法
2010/08/29 PHP
php数组保存文本与文本反编成数组实例
2014/11/13 PHP
php堆排序实现原理与应用方法
2015/01/03 PHP
yii2中使用Active Record模式的方法
2016/01/09 PHP
PHP微信分享开发详解
2017/01/14 PHP
使用PHPExcel实现数据批量导出为excel表格的方法(必看)
2017/06/09 PHP
使用JavaScript动态设置样式实现代码(2)
2013/01/25 Javascript
跟我学Nodejs(三)--- Node.js模块
2014/05/25 NodeJs
使用mouse事件实现简单的鼠标经过特效
2015/01/30 Javascript
JS自定义选项卡函数及用法实例分析
2015/09/02 Javascript
JavaScript操作HTML DOM节点的基础教程
2016/03/11 Javascript
Jquery元素追加和删除的实现方法
2016/05/24 Javascript
JavaScript中的await/async的作用和用法
2016/10/31 Javascript
文件上传,iframe跨域数据提交的实现
2016/11/18 Javascript
js图片轮播手动切换特效
2017/01/12 Javascript
使用Vue.js和Flask来构建一个单页的App的示例
2018/03/21 Javascript
关于JavaScript中高阶函数的魅力详解
2018/09/07 Javascript
详解Vue一个案例引发「内容分发slot」的最全总结
2018/12/02 Javascript
vue 对象添加或删除成员时无法实时更新的解决方法
2019/05/01 Javascript
Vue-cli3.x + axios 跨域方案踩坑指北
2019/07/04 Javascript
electron-vue开发环境内存泄漏问题汇总
2019/10/10 Javascript
vue实现Input输入框模糊查询方法
2021/01/29 Javascript
Vuex的实战使用详解
2019/10/31 Javascript
解决vue单页面应用进入页面加载所有 js 的问题
2020/08/12 Javascript
python绘图库Matplotlib的安装
2014/07/03 Python
编写Python脚本把sqlAlchemy对象转换成dict的教程
2015/05/29 Python
python多进程提取处理大量文本的关键词方法
2018/06/05 Python
Tensorflow读取并输出已保存模型的权重数值方式
2020/01/04 Python
Mavi牛仔裤美国官网:土耳其著名牛仔品牌
2016/09/24 全球购物
美国独家设计师眼镜在线光学商店:Glasses Gallery
2017/12/28 全球购物
党校培训自我鉴定
2014/02/01 职场文书
诚信考试承诺书
2014/03/27 职场文书
个人债务授权委托书
2014/10/17 职场文书
文明礼仪主题班会
2015/08/13 职场文书
Python实战之疫苗研发情况可视化
2021/05/18 Python