instanceof用于测试构造函数中的prototype属性是否出现在对象的原型链中的任何位置。
object instanceod constructor //object要检测的对象,constructor某个构造函数。
instanceof 运算符用来检测constructor.prototype是否存在于参数object的原型链
// 定义构造函数
function C(){}
function D(){}
var o = new C();
o instanceof C; // true,因为 Object.getPrototypeOf(o) === C.prototype
o instanceof D; // false,因为 D.prototype不在o的原型链上
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 因为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
几个示例子
"string" instanceof String //返回false,检查原型链会找到undefined。
new String() instanceof String //true
new String('string') instanceof String //true
new String() instanceof Object //true
({}) instanceof Object
Object.create(null) instanceof Object //false
new Date() instanceof Object //true
document.querySelector('img') instanceof Image // 可以来检测图片
注意:
!(obj instanceof constructor) 与!obj instanceof constructor
复杂用法
Object instanceof Object //true
Function instanceof Function //true
Number instanceof Number //false
String instanceof SString //false
//原因
Object.__proto__.__proto__===Object.prototype
Function.__proto__===Function.prototype
标准的代码翻译
function instance_of(L, R) {//L 表示左表达式,R 表示右表达式
var O = R.prototype;// 取 R 的显示原型
L = L.__proto__;// 取 L 的隐式原型
while (true) {
if (L === null)
return false;
if (O === L)// 这里重点:当 O 严格等于 L 时,返回 true
return true;
L = L.__proto__;
}
}
function InstanceOf(obj, Constructor) {
while (obj) {
if (obj === Constructor.prototype) {
return true;
}
obj = obj.__proto__
}
return false;
}
JavaScript原型继承机制
在JavaScript原型继承结构里面,规范中用[[Prototype]]表示对象隐式的原型,Chrome,FireFox可以使用proto访问到,所有的对象都有proto属性,只有Object.prototype.__prototype为null
总结
所有JavaScript对象或者函数 instanceof Object 为true。
所有函数instanceof Function 为true。
其他的JavaScript对象 instanceof自身。 因为构造函数的原型链上只有Function.prototype
和Object.prototype而没有他们自身的prototype
。