1、使用 typeof 操作符
let value = 123;
console.log(typeof value); // 输出 "number"
let str = "Hello, world!";
console.log(typeof str); // 输出 "string"
let bool = true;
console.log(typeof bool); // 输出 "boolean"
let obj = {};
console.log(typeof obj); // 输出 "object" (对于对象、数组、null 等都会返回 "object")
let func = function() {};
console.log(typeof func); // 输出 "function"
let und; // undefined
console.log(typeof und); // 输出 "undefined"
注意:
typeof null
会返回"object"
,这是 JavaScript 的历史遗留问题,实际上我们应该通过严格的相等性检查value === null
来判断是否为null
。
2、使用 instanceof
操作符
instanceof
用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。
let arr = [];
console.log(arr instanceof Array); // 输出 "true"
let date = new Date();
console.log(date instanceof Date); // 输出 "true"
3、Object.prototype.toString.call()
方法
这是一种更加准确地判断复杂类型的方法,尤其对于区分 null
和 object
类型很有用。
let num = 123;
console.log(Object.prototype.toString.call(num)); // 输出 "[object Number]"
let arr = [];
console.log(Object.prototype.toString.call(arr)); // 输出 "[object Array]"
let nul = null;
console.log(Object.prototype.toString.call(nul)); // 输出 "[object Null]"
4、自定义类型检测函数
当需要更细粒度的类型检查时,可以编写自定义函数,例如判断一个值是否为纯粹的数字(排除 Infinity
和 NaN
)或者进行更复杂的对象类型检查。
function getType(value) {
const type = typeof value;
if (type === 'object') {
if (value === null) {
return 'null';
} else if (Array.isArray(value)) {
return 'array';
} else if (value instanceof Date) {
return 'date';
} else if (typeof value.toString === 'function' && /^function (\w+)?\(/.test(value.toString())) {
return 'function';
} else {
// 这里还可以扩展对其他内置对象或其他自定义类实例的检测
return 'object';
}
} else if (type === 'number') {
if (isNaN(value)) {
return 'nan';
} else if (!isFinite(value)) {
return 'infinity';
} else {
return 'number';
}
}
return type;
}
// 示例用法:
let num = 42;
console.log(getType(num)); // 输出 "number"
let arr = [];
console.log(getType(arr)); // 输出 "array"
let func = function() {};
console.log(getType(func)); // 输出 "function"
let date = new Date();
console.log(getType(date)); // 输出 "date"
let nul = null;
console.log(getType(nul)); // 输出 "null"
let strNum = "123";
console.log(getType(strNum)); // 输出 "string"
5、ES6 中的 Symbol.toStringTag
可以通过 Symbol.toStringTag
定制对象在 Object.prototype.toString.call()
中的输出,从而实现更精确的类型检测。在ES6中,Symbol.toStringTag
是一个内置的 Symbol 值,它允许对象在其默认 toString()
行为被调用时自定义其输出。当使用 Object.prototype.toString.call(obj)
时,JavaScript引擎会查找对象上是否存在 Symbol.toStringTag
属性,并返回与该属性关联的字符串值(如果存在)。
let obj = {
[Symbol.toStringTag]: 'MyCustomType'
};
console.log(Object.prototype.toString.call(obj)); // 输出 "[object MyCustomType]"
这样就可以让自定义的对象类型在 toString()
方法被间接调用时,显示为自定义的类型名称,而不是默认的 "object"。
许多内置对象类型也使用了 Symbol.toStringTag
,比如 Set、Map、Promise 等,以确保它们在 Object.prototype.toString.call()
调用下能正确显示它们的类型名称。
此外,这个特性常用于库和框架中,以便开发者能够定制化他们的自定义类或对象在进行类型检查时的表现。