JavaScript —— 判断数据类型
一、JavaScript数据类型
最新的 ECMAScript 标准定义了 8 种数据类型:
7 种原始类型
undefined
null
Boolean
Number
String
Symbol
BigInt
对象
Object
二、判断JavaScript数据类型
1.typeof
-
typeof 操作符返回一个字符串,表示未经计算的操作数的类型。
-
记住 typeof 操作符的唯一目的就是检查数据类型,如果我们希望检查任何从 Object 派生出来的结构类型,使用 typeof 是不起作用的,因为总是会得到 “object”。
-
引用类型中的 数组、日期、正则 也都有属于自己的具体类型,而 typeof 对于这些类型的处理,只返回了处于其原型链最顶端的 Object 类型
-
typeof null === 'object';
-
typeof function() {} === 'function';
-
注意
Null
,Function
和包装类型
-
在 JavaScript 最初的实现中,JavaScript 中的值是由一个表示类型的标签和实际数据值表示的。对象的类型标签是 0。由于 null 代表的是空指针(大多数平台下值为 0x00),因此,null 的类型标签是 0,typeof null 也因此返回 “object”。
1.1 typeof 可能的返回值
类型 | 结果 |
---|---|
Undefined | “undefined” |
Null | “object” |
Boolean | “boolean” |
Number | “number” |
BigInt(ECMAScript 2020 新增) | “bigint” |
String | “string” |
Symbol (ECMAScript 2015 新增) | “symbol” |
宿主对象(由 JS 环境提供) | 取决于具体实现 |
Function 对象 (按照 ECMA-262 规范实现 [[Call]]) | “function” |
其他任何对象 | “object” |
1.2 示例
// 数值
typeof 37 === 'number';
typeof 3.14 === 'number';
typeof(42) === 'number';
typeof Math.LN2 === 'number';
typeof Infinity === 'number';
typeof NaN === 'number'; // 尽管它是 "Not-A-Number" (非数值) 的缩写
typeof Number(1) === 'number'; // Number 会尝试把参数解析成数值
typeof 42n === 'bigint';
// 字符串
typeof '' === 'string';
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';
// JavaScript 诞生以来便如此
typeof null === 'object';
// 对象
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';
复制代码
2.instanceof
2.1 介绍
-
instanceof
运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。 -
需要特别注意的是:instanceof 检测的是原型
-
instanceof 只能用来判断两个对象是否属于实例关系, 而不能判断一个对象实例具体属于哪种类型。
-
由下图可知
[] instanceof Array === true
,[] instanceof Object === true
,所以instanceof的检测并不是特别准确。 -
instanceof 的问题在于,它假定只有一个全局执行环境。
-
在不同window或者iframe间,不能使用instanceof。
-
还是以Array为例,在不同window或者iframe间的Array构造函数并不是同一个函数,可以认为是在不同的全局环境下的Array构造函数。
-
ECMAScript5新增了
Array.isArray()
方法,这个方法的目的是最终确定某个值到底是不是数组,而不管它是在哪个全局执行环境中创建的。