深入了解JavaScript当中如何确定值的类型
JavaScript是一种弱类型语言,当你给一个变量赋了一个值,该值是什么类型的,那么该变量就是什么类型的,并且你还可以给一个变量赋多种类型的值,也不会报错,这就是JavaScript的内部机制所决定的,那么当我们在使用一些方法的时候,必须知道该变量是什么类型的,才能调用该变量对应的一些方法,那么我们如何获取到值的变量呢?
这里我们有三种方法
1.typeof 2.instanceof 3.Object.prototype.toString 下面我将详细讲解一下这三个方法
typeof:
作用:判断一个变量类型
底层原理:js中为了提高性能效率,使用值编码来存储值的类型,读取值编码当中的类型标签位,根据标签值返回对应的类型字符串
类型判断流程:先区分「直接量」与「指针」
直接量表:
数据类型 | 存储形式 | 第 0 位 | 类型判定关键 |
---|---|---|---|
Boolean | 小整数(SMI) | 0 | 值为 0 或 2 ,且最低位为 0 (SMI 标记)。 |
Number(SMI) | 32 位有符号整数(SMI) | 0 | 值非 0 /2 ,且最低位为 0 (SMI 标记)。 |
Undefined | 全局特殊值(单例) | 无 | 直接比较值是否为 undefined 全局变量,typeof 直接返回 "undefined" 。 |
指针表:
数据类型 | 存储形式 | 低 3 位标签 | 类型判定关键 |
---|---|---|---|
普通 Object | 指针 | 000 | 低 3 位为 000 |
HeapNumber (浮点数) | 指针 | 001 | 低 3 位为 001 |
String | 指针 | 110 | 低 3 位为 110 |
Symbol | 指针 | 100 | 低 3 位为 100 |
BigInt | 指针 | 101 | 低 3 位为 101 |
Function (函数) | 指针 | 011 | 低 3 位为 011 |
null | 空指针 | 000 |
这里null比较特殊,他的低三位和对象object一样,所以会被typeof误判为object对象
这里举一些比较常见的事例:
console.log(typeof undefined); // 输出:"undefined"
console.log(typeof null); // 输出:"object"
console.log(typeof true); // 输出:"boolean"
console.log(typeof 42); // 输出:"number"
console.log(typeof "hello"); // 输出:"string"
console.log(typeof Symbol("key"));// 输出:"symbol"
console.log(typeof 100n); // 输出:"bigint"
console.log(typeof (() => {})); // 输出:"function"
console.log(typeof {}); // 输出:"object"//特殊情况
console.log(typeof /test/g); // "object"
console.log(typeof Infinity); // "number"
console.log(typeof NaN); // "number"
console.log(typeof undeclaredVar); // "undefined"(不会报错)
instanceof:
概念:instanceof 是一种操作符,用于判断一个对象是否是某个类(Class)或接口(Interface)的实例。这里需要注意的是,instanceof只能判断对象,不能判断基本类型
原理: instanceof 操作符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上 左边实例对象的内部属性通过 Object.getPrototypeOf() 方法来访问[[Prototype]]
//这里表示instanceof不能直接用于基本类型
console.log(42 instanceof Number); // false//可以将基本类型通过内置构造函数包装成对象
const numObj = new Number(42);
console.log(numObj instanceof Number); // trueconsole.log([] instanceof Array); // true
console.log([] instanceof Object); // true
console.log({} instanceof Object); // true
Object.prototype.toString:
概念:
这个方法可以判断一个变量的具体类型,是最精确的检测方式,返回的是一个【object type】格式字符串,它可以识别到所有内置对象的类型
使用方法:
// 基本类型和内置对象
Object.prototype.toString.call({}); // [object Object]
Object.prototype.toString.call([]); // [object Array]
Object.prototype.toString.call(new Date()); // [object Date]
Object.prototype.toString.call(new MyClass()); // [object Object] (默认)
和typeof对比:
类型 | typeof 结果 | Object.prototype.toString.call() 结果 |
---|---|---|
[] | "object" | [object Array] |
new Date() | "object" | [object Date] |
/abc/ | "object" | [object RegExp] |
null | "object" | [object Null] |
undefined | "undefined" | [object Undefined] |
Symbol(1) | "symbol" | [object Symbol] |