JavaScript的instanceof运算符学习教程
作者:韩子迟 发布时间:2024-04-17 10:09:59
语法
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
猜你喜欢
- 前言tips:第一次发技术文章,篇幅比较简短,主要采取文字和关键代码表现的形式,希望帮助到大家。(若有不正确还请多多指正)nextTick作
- python中的email模块可以方便的解析邮件,先上代码#-*- encoding: gb2312 -*-import osimport
- 一个客户提供一个股价的信息,要求放在页面上,显示一些数据,需要从远程获取xml,然后解析写在网页上,开始不会觉得很难,其实蛮简单的,先用ja
- 概念如果索引包含所有满足查询需要的数据的索引成为覆盖索引(Covering Index),也就是平时所说的不需要回表操作判断标准使用expl
- 最近一个小项目需要一个星级评分的效果,所以去淘宝偷了一个,但是还得加载YUI很不爽,还是自己动手写一个吧~HTML: <!-
- 前言在python 中有时候我们用数组操作数据可以极大的提升数据的处理效率,类似于R的向量化操作,是的数据的操作趋于简单化,在python
- jwt的问题首先说明一个jwt存在的问题,也就是要替换jwt的原因:jwt无法在服务端主动退出的问题jwt无法作废已颁布的令牌,只能等到令牌
- 代码: import os while True: dynamic = input('输入计算表达式:') if dynam
- 我就废话不多说了,大家还是直接看代码吧!# 在setting设置外键'OPTIONS': { "in
- mysql可以通过下面语句判断是否支持分区:SHOW VARIABLES LIKE '%partition%';如果输出:h
- 传染源: 野生动物,可能为中华菊头蝠病毒: 新型冠状病毒 2019-nCoV传播途径: 经呼吸道飞沫传播,亦可
- 本文实例主要是实现爬取一个网页上的图片地址,具体如下。读取一个网页的源代码:import urllib.requestdef getHtml
- 1.创建数据库连接,并打开set cnn=Server.CreateObject("ADODB.Connection&q
- caller 属性返回一个对函数的引用,该函数调用了当前函数。functionName.caller functionName 对象是所执行
- 以下代码实现了ip查询功能处理程序 import os,timedef getip(filepath):
- 如果使用的是matplotlib绘图,可以通过以下命令更改图片的大小:%matplotlib linline如果是 plt.figure(f
- 本文旨在给大家提供一种构建一个完整 UI 库脚手架的思路:包括如何快速并优雅地构建UI库的主页、如何托管主页、如何编写脚本提升自己的开发效率
- 所谓天赋(左脑和右脑)也就是你是否有艺术天赋,天赋也许是存在的,这主要在于人类左右脑的分工。左脑主要负责逻辑理解、语言、判断、分类、分析、推
- 1、cat:拼接直接合并数据2、stack拼接:与cat不同的是,stack创建了一个新的维度,在拼接的同时,给数据增加了类别。并且stac
- 科学设计你的网站网页:来自 Eye-Tracking研究的23节必修课 ——Christina Laun在网络设计领域关于Eye-