前端知识速记–JS篇:instanceof
在JavaScript中,instanceof
运算符用于检测一个对象是否是另一个对象的实例。它的基本语法为:obj instanceof Constructor
。如果obj
是Constructor
的实例,它将返回true
,否则返回false
。这是一个判断对象的原型链上是否存在构造函数的prototype
属性的简单方法。
1. instanceof
的基本用法
示例
function Animal() {}
function Dog() {}
Dog.prototype = Object.create(Animal.prototype);
const dog = new Dog();
console.log(dog instanceof Dog); // true
console.log(dog instanceof Animal); // true
console.log(dog instanceof Object); // true
console.log(dog instanceof Array); // false
在上述代码中:
dog instanceof Dog
返回true
,因为dog
是Dog
的实例。dog instanceof Animal
也返回true
,因为Dog
继承自Animal
,dog
通过原型链链接到Animal
。dog instanceof Object
返回true
,因为所有对象都是Object
的实例。dog instanceof Array
返回false
,因为dog
并非Array
的实例。
2. instanceof
与typeof
的比较
typeof
的特点
typeof
运算符用于获取变量的数据类型,它的语法为:typeof variable
。返回的结果是一个字符串,表示变量的数据类型。它有局限性,尤其在判断null
时:
console.log(typeof null); // "object"
为什么typeof null
返回"object"
?
这是JavaScript语言设计中的一个历史遗留问题。在最初的JavaScript版本中,所有对象的类型都被定义为对象,并且在内存中null
的表示方式也是以对象的形式。因此,当typeof
检查到null
时,它看到了对象的表示,返回了"object"
。这个行为虽然被广泛认为是一个 bug,但在后续版本中为了兼容性并未被更改。
instanceof
对比
instanceof
专注于对象的类型(即原型链),能够准确判断对象是否为某个构造函数的实例。typeof
适用于 primitive value 和一些非对象类型,但因为历史原因对null
处理不当,使其在类型判断上显得薄弱。
const value = null;
console.log(typeof value); // "object"
console.log(value instanceof Object); // false
在这个例子中,虽然typeof null
返回object
,但是instanceof
运算符却正确地反映出null
并不是一个对象实例,因为它没有原型链。
3. 经典问题
经典问题:如何判断一个变量既不是null
也不是数组?
使用instanceof
和typeof
结合的方式,可以有效判断:
function isObject(value) {
return value !== null && typeof value === 'object';
}
console.log(isObject([])); // true
console.log(isObject({})); // true
console.log(isObject(null)); // false
console.log(isObject(42)); // false
该函数定义了在判断对象之前,先排除了null
的情况。