typeof 实现原理

2023-05-17 15:23:58 浏览数 (1)

# 介绍

# Try it

typeof (opens new window) 操作符返回一个字符串,表示未经计算的操作数的类型。

代码语言:javascript复制
typeof 42; // "number"

typeof 'cellinlab'; // "string"

typeof true; // "boolean"

typeof undeclaredVariable; // "undefined"

# 描述

typeof 可能的返回值。

类型

结果

Undefined (opens new window)

undefined

Null (opens new window)

object

Boolean (opens new window)

boolean

Number (opens new window)

number

BigInt (opens new window)

bigint

String (opens new window)

string

Symbol (opens new window)

symbol

Function (opens new window)

function

宿主对象(由 JS 环境提供)

取决于具体实现

其他任何对象

object

# 示例

代码语言:javascript复制
// 数值
typeof 42; // "number"
typeof 3.14; // "number"
typeof(42); // "number"
typeof Math.LN2; // "number"
typeof Infinity; // "number"
typeof NaN; // "number"
typeof Number(1); // "number"

typeof 42n; // "bigint"

// 字符串
typeof ''; // "string"
typeof 'cellinlab'; // "string"
typeof `template literal`; // "string"
typeof '2021'; // "string"
typeof (typeof 2021); // "string" typeof 总是返回一个字符串
typeof String(2021); // "string" String() 会将任意值转换为 字符串,比 toString 更安全

// 布尔值
typeof true; // "boolean"
typeof false; // "boolean"
typeof Boolean(1); // "boolean" Boolean() 会基于参数是真值还是虚值进行转换
typeof !!(1); // "boolean" !! 相当于 Boolean()

// Symbol
typeof Symbol(); // "symbol"
typeof Symbol('cellinlab'); // "symbol"
typeof Symbol.iterator; // "symbol"

// Undefined
typeof undefined; // "undefined"
typeof undeclaredVariable; // "undefined"

// 对象
typeof {}; // "object"

// 使用 Array.isArray() 或者 Object.prototype.toString.call() 区分数组和对象
Array.isArray([1, 2, 3]); // true
Object.prototype.toString.call([1, 2, 3]); // "[object Array]"
typeof [1, 2, 3]; // "object"

typeof new Date(); // "object"
typeof /regex/; // "object"

// 一些令人迷惑的地方
typeof new Boolean(true); // "object"
typeof new Number(1); // "object"
typeof new String('cellinlab'); // "object"

// 这里会更加迷惑
var func = new Function();
typeof func; // "function"

// 函数
typeof function() {}; // "function"
typeof class C {}; // "function"
typeof Math.sin; // "function"

// null
typeof null; // "object"

# 实现原理

JavaScript 在底层存储变量时,会在变量的机器码低位 1-3 位存储它的类型信息:

  • 000: 对象
  • 010: 浮点数
  • 100: 字符串
  • 110: 布尔值
  • 1: 整数

其中,nullundefined 信息存储比较特殊:

  • null,所有机器码均为 0
  • undefined,用 -2^32 整数来表示

typeof 在 判断 null 的时候,由于 null 的所有机器码均为 0,因此直接被判断为 object

但是,如果在使用 instanceof 时,null 又不被认为是 object:

代码语言:javascript复制
null instanceof null;
// TypeError: Right-hand side of 'instanceof' is not an object

这是 JavaScript 的历史遗留 bug。

在用 typeof 来判断变量类型的时候,需要注意,最好用 typeof 来判断基本数据类型,避免对 null 的判断。

或者推荐直接使用 Object.prototype.toString 来判断:

代码语言:javascript复制
Object.prototype.toString.call(1); // "[object Number]"
Object.prototype.toString.call('cellinlab'); // "[object String]"
Object.prototype.toString.call({a: 2021}); // "[object Object]"
Object.prototype.toString.call([1]); // "[object Array]"
Object.prototype.toString.call(true); // "[object Boolean]"
Object.prototype.toString.call(() => {}); // '[object Function]'
Object.prototype.toString.call(null); // "[object Null]"
Object.prototype.toString.call(undefined); // "[object Undefined]"
Object.prototype.toString.call(Symbol(1)); // "[object Symbol]"

0 人点赞