语法
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
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
更新日志
- 群星2013-青春缤纷辑压箱宝大公开3CD2[新加坡限量版][WAV整轨]
- 林育群.2013-BalladShow(日本版)【环球】【WAV+CUE】
- 陈加洛.1992-痛到感觉不到【宝丽金】【WAV+CUE】
- 群星.2023-宿命之敌电视剧原声带【韶愔音乐】【FLAC分轨】
- 東京事変-大発見[FLAC+CUE]
- 椎名林檎-三文ゴシップ[FLAC+CUE]
- 2024年08月04日
- 裘德《裘德「最后的水族馆」演唱会LIVE》[320K/MP3][228.89MB]
- 裘德《裘德「最后的水族馆」演唱会LIVE》[24bit 48kHz][FLAC/分轨][2.08G]
- 基因三重奏《如果你什么都不说 音乐会现场录音》[320K/MP3][145.37MB]
- 孟庭苇.1996-月亮说话(2020环球24KGOLD限量版)【上华】【WAV+CUE】
- 群星.1997-新艺宝优质音响系列·国语精选监听版【新艺宝】【WAV+CUE】
- 阿桑.2005-寂寞在唱歌(星外星引进版)【华研国际】【WAV+CUE】
- 基因三重奏《如果你什么都不说 音乐会现场录音》[FLAC/分轨][287.43MB]
- 蔡题谦《我爱你,却依然要看你走》[320K/MP3][88.65MB]