instanceof运算符可以用来判断某个构造函数的prototype属性是否存在另外一个要检测对象的原型链上。
实例一:普遍用法
A instanceof B :检测B.prototype是否存在于参数A的原型链上.
1 |
function Ben() { |
2 |
3 |
} |
4 |
var ben = new Ben(); |
5 |
console.log(ben instanceof Ben); //true |
实例二:继承中判断实例是否属于它的父类
1 |
function Ben_parent() {} |
2 |
function Ben_son() {} |
3 |
Ben_son.prototype = new Ben_parent(); //原型继承 |
4 |
var ben_son = new Ben_son(); |
5 |
console.log(ben_son instanceof Ben_son); //true |
6 |
console.log(ben_son instanceof Ben_parent); //true |
实例三:复杂用法
1 |
function Ben() {} |
2 |
console.log(Object instanceof Object); //true |
3 |
console.log(Function instanceof Function); //true |
4 |
console.log(Function instanceof Object); //true |
5 |
console.log(Ben instanceof Function); //true |
6 |
7 |
console.log(String instanceof String); //false |
8 |
console.log(Boolean instanceof Boolean); //false |
9 |
console.log(Ben instanceof Ben); //false |
看到上述的结果,是否有点懵了,究其原因,还需探其原理,下面我们来看看规范中如何定义的。
01 |
ECMASCRIPT 5.1 Standard文档中的定义: |
02 |
11.8.6 The instanceof operator |
03 |
04 |
The production RelationalExpression : RelationalExpression instanceof ShiftExpression is evaluated as follows: |
05 |
06 |
1.Let lref be the result of evaluating RelationalExpression. |
07 |
2.Let lval be GetValue(lref). |
08 |
3.Let rref be the result of evaluating ShiftExpression. |
09 |
4.Let rval be GetValue(rref). |
10 |
5.If Type(rval) is not Object, throw a TypeError exception. |
11 |
6.If rval does not have a [[HasInstance]] internal method, throw a TypeError exception. |
12 |
7.Return the result of calling the [[HasInstance]] internal method of rval with argument lval. |
13 |
14 |
15.3.5.3 [[HasInstance]] (V) |
15 |
16 |
Assume F is a Function object. |
17 |
18 |
When the [[HasInstance]] internal method of F is called with value V, the following steps are taken: |
19 |
20 |
//V不是对象,直接返回false |
21 |
1.If V is not an object, return false. |
22 |
23 |
//用 [[Get]] 方法取 F方法的prototype属性,结果赋值给O |
24 |
2.Let O be the result of calling the [[Get]] internal method of F with property name "prototype". |
25 |
26 |
//如果O不是一个对象,报告异常 |
27 |
3.If Type(O) is not Object, throw a TypeError exception. |
28 |
29 |
//重复循环 |
30 |
4.Repeat |
31 |
//V = V.[[Prototype]] |
32 |
a.Let V be the value of the [[Prototype]] internal property of V. |
33 |
b.If V is null, return false. |
34 |
c.If O and V refer to the same object, return true. |
35 |
36 |
NOTE Function objects created using Function.prototype.bind have a different implementation of [[HasInstance]] defined in 15.3.4.5.3. |
对应上述规范做个函数模拟A instanceof B:
01 |
function _instanceof(A, B) { |
02 |
var O = B.prototype; // 取B的显示原型 |
03 |
A = A.__proto__; // 取A的隐式原型 |
04 |
while ( true ) { |
05 |
//Object.prototype.__proto__ === null |
06 |
if (A === null ) |
07 |
return false ; |
08 |
if (O === A) // 这里重点:当 O 严格等于 A 时,返回 true |
09 |
return true ; |
10 |
A = A.__proto__; |
11 |
} |
12 |
} |
使用此函数模拟解析过程:
01 |
Object instanceof Object解析,执行_instanceof (Object, Object) |
02 |
O = Object.prototype; |
03 |
A = Object.__proto__ = Function.prototype |
04 |
A = Function.prototype.__proto__ = Object.prototype |
05 |
return true ; |
06 |
07 |
Function instanceof Function解析,执行_instanceof (Function, Function) |
08 |
O = Function.prototype; |
09 |
A = Function.__proto__ = Function.prototype; |
10 |
return true ; |
11 |
12 |
Function instanceof Object解析,执行_instanceof (Function, Object) |
13 |
O = Object.prototype; |
14 |
A = Function.__proto__ = Function.prototype; |
15 |
A = Function.prototype.__proto__ = Object.prototype; |
16 |
return true ; |
17 |
18 |
String instanceof String解析,执行_instanceof (String, String) |
19 |
O = String.prototype; |
20 |
A = String.__proto__ = Function.prototype; |
21 |
A = Function.prototype.__proto__ = Object.prototype; |
22 |
A = Object.prototype.__proto__ = null ; |
23 |
return false ; |
24 |
25 |
Ben instanceof Ben解析,执行_instanceof (Ben, Ben) |
26 |
O = Ben.prototype; |
27 |
A = Ben.__proto__ = Ben.prototype; |
28 |
A = Ben.prototype.__proto__ = Object.prototype; |
29 |
A = Object.prototype.__proto__ = null ; |
30 |
return false ; |
参考链接:
http://www.zuojj.com/tdocs/es5.1/#sec-11.8.6
http://blog.csdn.net/cuew1987/article/details/15498121
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/instanceof
转载声明:
本文标题:深入javascript(六):instanceof 运算符
本文链接:http://www.zuojj.com/archives/393.html,转载请注明转自Benjamin-专注前端开发和用户体验
http://www.zuojj.com/archives/393.html
时间: 2024-08-24 04:22:53