instanceof用于测试构造函数中的prototype属性是否出现在对象的原型链中的任何位置。
instanceof运算符 - 图1

  1. object instanceod constructor //object要检测的对象,constructor某个构造函数。

instanceof 运算符用来检测constructor.prototype是否存在于参数object的原型链

  1. // 定义构造函数
  2. function C(){}
  3. function D(){}
  4. var o = new C();
  5. o instanceof C; // true,因为 Object.getPrototypeOf(o) === C.prototype
  6. o instanceof D; // false,因为 D.prototype不在o的原型链上
  7. o instanceof Object; // true,因为Object.prototype.isPrototypeOf(o)返回true
  8. C.prototype instanceof Object // true,同上
  9. C.prototype = {};
  10. var o2 = new C();
  11. o2 instanceof C; // true
  12. o instanceof C; // false,C.prototype指向了一个空对象,这个空对象不在o的原型链上.
  13. D.prototype = new C(); // 继承
  14. var o3 = new D();
  15. o3 instanceof D; // true
  16. o3 instanceof C; // true 因为C.prototype现在在o3的原型链上

注意:obj instanceof Foo 返回true,并不意味永远会返回true,因为Foo.prototype属性的值可能会改变,对象obj的原型链的情况也会改变。目前规范中,可以使用非标准的proto伪属性改变,比如说obj.proro={}。

instanceof和全局对象(多个iframe或多个window之间交互)

浏览器中,脚本可能会在多个窗口之间进行交互,多个窗口->多个全局环境,不同的全局环境拥有不同的全局对象。拥有不同的内置类型的构造函数。引发问题比如说[] instanceof window.frames[0].Array返回false。因为Array.prototype!===window.frames[0].Array.prototype。比如数组的校验可以使用Array.isArray()或者Object.prototype.toString.call(obj)==="[object Array]]来安全的检测传过来的对象是否是一个数组。

检测一个Nodes在另一个窗口中是不是SVGElement,你可以使用myNode instanceof myNode.ownerDocument.defaultView.SVGElement

几个示例子

  1. "string" instanceof String //返回false,检查原型链会找到undefined。
  2. new String() instanceof String //true
  3. new String('string') instanceof String //true
  4. new String() instanceof Object //true
  5. ({}) instanceof Object
  6. Object.create(null) instanceof Object //false
  7. new Date() instanceof Object //true
  8. document.querySelector('img') instanceof Image // 可以来检测图片

注意:

  1. !(obj instanceof constructor) 与!obj instanceof constructor

复杂用法

  1. Object instanceof Object //true
  2. Function instanceof Function //true
  3. Number instanceof Number //false
  4. String instanceof SString //false
  5. //原因
  6. Object.__proto__.__proto__===Object.prototype
  7. Function.__proto__===Function.prototype

标准的代码翻译

  1. function instance_of(L, R) {//L 表示左表达式,R 表示右表达式
  2. var O = R.prototype;// 取 R 的显示原型
  3. L = L.__proto__;// 取 L 的隐式原型
  4. while (true) {
  5. if (L === null)
  6. return false;
  7. if (O === L)// 这里重点:当 O 严格等于 L 时,返回 true
  8. return true;
  9. L = L.__proto__;
  10. }
  11. }
  1. function InstanceOf(obj, Constructor) {
  2. while (obj) {
  3. if (obj === Constructor.prototype) {
  4. return true;
  5. }
  6. obj = obj.__proto__
  7. }
  8. return false;
  9. }

JavaScript原型继承机制

在JavaScript原型继承结构里面,规范中用[[Prototype]]表示对象隐式的原型,Chrome,FireFox可以使用proto访问到,所有的对象都有proto属性,只有Object.prototype.__prototype为null

总结

所有JavaScript对象或者函数 instanceof Object 为true。
所有函数instanceof Function 为true。
其他的JavaScript对象 instanceof自身。 因为构造函数的原型链上只有Function.prototypeObject.prototype而没有他们自身的prototype