在JavaScript中,你可以用不同的方式检测数据类型。这是因为JavaScript是一种弱类型或动态语言,变量没有预先定义的类型。以下是一些常用的数据类型检测方法:
一、typeof
1、描述
typeof 运算符返回一个字符串,表示操作数的类型
typeof 可能的返回值:
类型 | 结果 |
---|---|
Undefined | “undefined” |
Null | “object” |
Boolean | “boolean” |
Number | “number” |
BigInt | “bigint” |
String | “string” |
Symbol | “symbol” |
Function | “function” |
其他任何对象 | “object” |
2、示例
2.1 基本用法:
// 数值
typeof 37 === "number";
typeof 3.14 === "number";
typeof Math.LN2 === "number";
typeof Infinity === "number";
typeof NaN === "number"; // 尽管它是 "Not-A-Number" (非数值) 的缩写
typeof Number(1) === "number"; // Number 会尝试把参数解析成数值
typeof Number("shoe") === "number"; // 包括不能将类型强制转换为数字的值
typeof 42n === "bigint";
// 字符串
typeof "bla" === "string";
typeof `template literal` === "string";
typeof "1" === "string"; // 注意内容为数字的字符串仍是字符串
typeof typeof 1 === "string"; // typeof 总是返回一个字符串
typeof String(1) === "string"; // String 将任意值转换为字符串,比 toString 更安全
// 布尔值
typeof true === "boolean";
typeof false === "boolean";
typeof Boolean(1) === "boolean"; // Boolean() 会基于参数是真值还是虚值进行转换
typeof !!1 === "boolean"; // 两次调用 !(逻辑非)运算符相当于 Boolean()
// Symbols
typeof Symbol() === "symbol";
typeof Symbol("foo") === "symbol";
typeof Symbol.iterator === "symbol";
// Undefined
typeof undefined === "undefined";
typeof declaredButUndefinedVariable === "undefined";
typeof undeclaredVariable === "undefined";
// 对象
typeof { a: 1 } === "object";
// 使用 Array.isArray 或者 Object.prototype.toString.call
// 区分数组和普通对象
typeof [1, 2, 4] === "object";
typeof new Date() === "object";
typeof /regex/ === "object";
// 下面的例子令人迷惑,非常危险,没有用处。避免使用它们。
typeof new Boolean(true) === "object";
typeof new Number(1) === "object";
typeof new String("abc") === "object";
// 函数
typeof function () {} === "function";
typeof class C {} === "function";
typeof Math.sin === "function";
typeof null:
// JavaScript 诞生以来便如此
typeof null === "object";
在 JavaScript 最初的实现中,JavaScript 中的值是由一个表示类型的标签和实际数据值表示的。对象的类型标签是 0。由于 null 代表的是空指针(大多数平台下值为 0x00),因此,null 的类型标签是 0,typeof null 也因此返回 “object”
二、instanceof
instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上
简单地说,它可以用来判断一个对象是否是某个特定构造函数创建的实例,或者说一个对象是否继承自某个构造函数
1、语法
object instanceof constructor
- object : 某个实例对象
- constructor : 某个构造函数
2、示例
// 定义构造函数
function C() {}
function D() {}
var o = new C();
o instanceof C; // true,因为 Object.getPrototypeOf(o) === C.prototype
o instanceof D; // false,因为 D.prototype 不在 o 的原型链上
o instanceof Object; // true,因为 Object.prototype.isPrototypeOf(o) 返回 true
C.prototype instanceof Object; // true,同上
C.prototype = {};
var o2 = new C();
o2 instanceof C; // true
o instanceof C; // false,C.prototype 指向了一个空对象,这个空对象不在 o 的原型链上。
D.prototype = new C(); // 继承
var o3 = new D();
o3 instanceof D; // true
o3 instanceof C; // true 因为 C.prototype 现在在 o3 的原型链上
三、Object.prototype.toString.call()
1、描述
通常我们用typeof运算符或instanceof运算符来检测一个变量的类型,但这两种方式有时候不能给出我们想要的详细信息
Object.prototype.toString.call() 提供了一种更可靠的类型检测方法。
说明:
- 适用于判断JavaScript的内置类型(如String、Number、Array、Function、Object、Date等),因为当它被调用时,会返回一个标准化的字符串,该字符串明确地表明了目标对象的内置类型
- 对于用户自定义的对象类型,Object.prototype.toString.call 返回的字符串总是[object Object],如果需要判断自定义对象类型,则使用
instanceof
2、语法
Object.prototype.toString.call(value)
- value 是任何类型的对象,函数将返回该对象的类类型信息
- 返回一个表示对象类型的字符串。这个字符串的格式总是[object Type],其中Type是对象的类型
3、示例
Object.prototype.toString.call(2); // "[object Number]"
Object.prototype.toString.call(true); // "[object Boolean]"
Object.prototype.toString.call('hello'); // "[object String]"
Object.prototype.toString.call([]); // "[object Array]"
Object.prototype.toString.call(function(){}); // "[object Function]"
Object.prototype.toString.call({}); // "[object Object]"
Object.prototype.toString.call(null); // "[object Null]"
Object.prototype.toString.call(undefined); // "[object Undefined]"
Object.prototype.toString.call(new Date()); // "[object Date]"
Object.prototype.toString.call(Math); // "[object Math]"
Object.prototype.toString.call(new Error()); // "[object Error]"
4、通用判断方法
附上 vue 源码的封装方法:
function toRawType(value) {
return Object.prototype.toString.call(value).slice(8, -1);
}
测试:
toRawType(null) // Null
toRawType([]) // Array
toRawType('hello') // String
toRawType(24) // Number
toRawType(undefined) // Undefined
toRawType({name: 'hello'}) // Object