JavaScript 中的 instanceof 和 typeof
本博客 hjy-xh,转载请申明出处
instanceof
instanceof
运算符用于检测构造函数的prototype
属性是否出现在某个实例对象的原型链上
当然,instanceof
也可以判断一个实例是否是其祖先类型的实例。
1 2 3 4 5 6 7 8 9 10
| function Car(make, model, year) { this.make = make; this.model = model; this.year = year; } const auto = new Car('Honda', 'Accord', 1998);
console.log(auto instanceof Car);
console.log(auto instanceof Object);
|
根据原型和原型链的相关知识,这里进行一个实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| function myInstanceof(obj, target) { let targetPrototype = target.prototype; let objPrototype = obj.__proto__;
while(true) { if(objPrototype === null) { return false; } if(objPrototype === targetPrototype) { return true; } objPrototype = objPrototype.__proto__; } }
|
typeof
typeof
操作符返回一个字符串,表示未经计算的操作数的类型
这里用一张表来总结typeof
的使用情况:
类型 |
结果 |
Undefined |
‘undefined’ |
Null |
‘object’ |
Boolean |
‘boolean’ |
Number |
‘number’ |
BigInt |
‘bigint’ |
String |
‘string’ |
Symbol |
‘symbol’ |
Function |
‘function’ |
其它任何对象 |
‘object’ |
眼尖的小伙伴肯定发现了该操作符对于null
的执行结果有些奇怪,
1 2
| typeof null === 'object';
|
在JavaScript最初的实现中,底层存储变量的时候,会在变量的机器码的低位1-3位存储其类型信息:
- 000:对象
- 010:浮点数
- 100:字符串
- 110:布尔
- 1:整数
由于null
代表的空指针(大多数平台下值为0X00, 所有机器码均为0),因此typeof null
也因此返回 'object'
。
这也是 JavaScript 的历史遗留bug。
从上面的分析看出,在使用typeof
来判断变量类型时,需要避免对null
的判断。还有一个不错的判断类型的方法,就是Object.prototype.toString
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| Object.prototype.toString.call(0)
Object.prototype.toString.call('hi')
Object.prototype.toString.call({food:'cola'})
Object.prototype.toString.call([1,'a'])
Object.prototype.toString.call(true)
Object.prototype.toString.call(() => {})
Object.prototype.toString.call(null)
Object.prototype.toString.call(undefined)
Object.prototype.toString.call(Symbol(1))
|
参考
浅谈 instanceof 和 typeof 的实现原理
typeof mdn
instanceof mdn