JavaScript的instanceof操作符

原文:The instanceof Operator in JavaScript

instanceof运算符可以确定一个对象是否是一个类的实例。

instanceof运算符可以判断一个对象是否是某个JavaScript类的实例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Rectangle {
constructor(height, width) {
this.height = height;
this.width = width;
}
}

const obj = new Rectangle(3, 5);
obj.height; // 3
obj.width; // 5

// `instanceof` 关键字判断一个对象是否由特定类创建
obj instanceof Rectangle; // true
({}) instanceof Rectangle; // false

技术上来讲,instanceof运算符检查对象的原型链,看原型链上有没有constructor等于给定的类。这样,如果存在继承关系,子类的实例同样也是基类的一个实例。

1
2
3
4
5
6
7
class BaseClass {}
class SubClass extends BaseClass {}

const obj = new SubClass();

obj instanceof SubClass; // true
obj instanceof BaseClass; // true

Object类

Object是所有JavaScript类的基类。

1
2
3
4
5
6
7
class MyClass {}

const obj = new MyClass();

obj instanceof Object; // true
({}) instanceof Object; // true
null instanceof Object; // false

你可能会想到用v instanceof Object检查v是否是对象。在大部分场景是可行的,但在某些情况下对象不是Object的实例

1
2
3
4
5
6
7
8
9
10
11
12
13
// `Object.prototype` 从技术上来说不是 `Object` 的实例
// 因为原型链总是要结束的
// 译注:Object.prototype是原型链的终点不再向上追溯
typeof Object.prototype; // 'object'
Object.prototype instanceof Object; // false

// 将函数的`prototype`设置为`Object.create(null)`
// `Object`不在对象的原型链中
function MyClass() {}
MyClass.prototype = Object.create(null);

typeof new MyClass(); // 'object'
(new MyClass()) instanceof Object; // false

异常情况

instanceof运算符在右侧不是函数时会抛出错误。

译注:函数的判断依据是typeof a === 'function',ES6的类也是函数

1
2
3
4
5
6
7
8
9
10
11
class MyClass {}

function MyOtherClass() {}

const obj = {};

obj instanceof MyClass; // false
obj instanceof MyOtherClass; // false

// Throws "TypeError: Right-hand side of 'instanceof' is not callable"
obj instanceof { answer: 42 };