类型判断在编程、数据处理、逻辑控制等场景中是核心操作,其应用覆盖各个开发环节,接下来让我们学习JavaScript中类型判断的主要四个方法,了解它们的优缺点和适用场景,以便更好的使用它们。
typeof
typeof undefined; // "undefined"
typeof 42; // "number"
typeof "hello"; // "string"
typeof true; // "boolean"
typeof Symbol(); // "symbol"
typeof 123n; // "bigint"
typeof function() {}; // "function"
typeof [1, 2, 3]; // "object" (数组属于特殊对象)
typeof null; // "object" (历史遗留bug)
typeof new Date(); // "object"
typeof /regex/; // "object"
- typeof 可以准确判断除了null以外的基本类型
- typeof 对于引用类型来说,除了function会返回function,其他的都返回object
工作原理
- typeof 是通过将值转换为二进制来判断类型的,对于二进制前三位是 0 的统一识别为对象,所有的引用类型二进制前三位都是0,而null全是0
instanceof
const arr = [1, 2, 3];
arr instanceof Array; // true
arr instanceof Object; // true(所有对象都是Object的实例)
const date = new Date();
date instanceof Date; // true
class Person {}
const p = new Person();
p instanceof Person; // true
instanceof 可以准确的判断复杂引用类型,但是不能正确判断基本数据类型
工作原理
instanceof 内部机制是通过检查对象的原型链中是否包含指定构造函数的 prototype 属性,
基本类型默认不访问原型,所以不能正常判断基本数据类型
用代码来描述是不是更易懂一些
function myInstanceof(L,R){
L=L.__proto__;
while(L){
if(L===R.prototype){
return true
}
L=L.__proto__;
}
return false
}
Object.propotype.toString.call()
Object.prototype.toString.call(undefined); // "[object Undefined]"
Object.prototype.toString.call(null); // "[object Null]"
Object.prototype.toString.call(42); // "[object Number]"
Object.prototype.toString.call([1, 2, 3]); // "[object Array]"
Object.prototype.toString.call(/regex/); // "[object RegExp]"
Object.prototype.toString.call(new Date()); // "[object Date]"
Object.prototype.toString.call(function() {}); // "[object Function]"
- 能够准确识别对象的具体类型,包括内置对象和自定义对象。
- 适用于所有数据类型,包括基本数据类型和复杂数据类型。
- 返回一个格式为
[object Type]的字符串,其中Type表示对象的类型。
工作原理
Object.prototype.toString ( )
来自--Annotated ES5
- 如果
this值未定义,返回"[object undefined]"。 - 如果
this值为null,则返回"[object null]"。 - 设
object为传递this值作为参数调用toObject的结果。 - 设
class为对象的内部属性[[class]]的值。 - 返回三个字符串“[object ”, class和“]”连接后的String值。
Object.propotype.toString.call()
在 Object.prototype.toString.call(obj) 中:
this被绑定到obj,即toString()方法执行时的上下文对象是obj。obj的 [[Class]] 属性被读取,生成对应的类型字符串。
Array.isArray()
判断一个值是否为数组。
Array.isArray([1, 2, 3]); // true
Array.isArray({}); // false
总结
| 方法 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
typeof | 基本类型判断(除 null) | 简单、性能高 | 无法区分对象、数组等 |
instanceof | 对象是否为特定构造函数的实例 | 支持自定义类 | 不支持基本类型、跨窗口问题 |
Object.prototype.toString | 精确判断所有内置类型 | 最全面、最可靠 | 语法冗长 |
Array.isArray() | 判断数组 | 专门为数组设计 | 只能判断数组 |
根据具体场景选择合适的方法,通常优先使用 typeof 和 Array.isArray(),复杂场景使用 Object.prototype.toString。