JavaScript 中 typeof 实现原理

简介: JavaScript 中 typeof 实现原理

介绍

Try it

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

typeof 42; // "number"

typeof 'cellinlab'; // "string"

typeof true; // "boolean"

typeof undeclaredVariable; // "undefined"

描述

typeof 可能的返回值。

类型 结果
Undefined undefined
Null object
Boolean boolean
Number number
BigInt bigint
String string
Symbol symbol
Function function
宿主对象(由 JS 环境提供) 取决于具体实现
其他任何对象 object

示例

// 数值
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:

null instanceof null;
// TypeError: Right-hand side of 'instanceof' is not an object

这是 JavaScript 的历史遗留 bug。

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

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

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]"
相关文章
|
1月前
|
自然语言处理 JavaScript 前端开发
探索JavaScript中的闭包:理解其原理与实际应用
探索JavaScript中的闭包:理解其原理与实际应用
19 0
|
3月前
|
前端开发 JavaScript 算法
【面试题】 JavaScript 中的深浅拷贝: 原理与实现
【面试题】 JavaScript 中的深浅拷贝: 原理与实现
|
3月前
|
JavaScript 数据可视化
基于fabric.js的图片编辑器, 画布背景实现原理
基于vue3 + fabric.js + vite + element-plus + typescript等技术,画布背景原理分析
基于fabric.js的图片编辑器, 画布背景实现原理
|
3月前
|
Web App开发 JavaScript 前端开发
Node.js 的事件循环原理、工作流程
Node.js 的事件循环原理、工作流程
52 0
|
1月前
|
JavaScript
JS数组增删方法的原理,使用原型定义
JS数组增删方法的原理,使用原型定义
|
4天前
|
前端开发 JavaScript 编译器
深入解析JavaScript中的异步编程:Promises与async/await的使用与原理
【4月更文挑战第22天】本文深入解析JavaScript异步编程,重点讨论Promises和async/await。Promises用于管理异步操作,有pending、fulfilled和rejected三种状态。通过.then()和.catch()处理结果,但可能导致回调地狱。async/await是ES2017的语法糖,使异步编程更直观,类似同步代码,通过事件循环和微任务队列实现。两者各有优势,适用于不同场景,能有效提升代码可读性和维护性。
|
15天前
|
JavaScript 前端开发
JS中的typeof
`typeof`操作符在JavaScript中用于检测变量的数据类型。然而,它并非总是完全准确,如:数组和null被错误地标记为'object',NAN是'number',Symbol是'function',而Array也是'function'。注意`undefined`返回'undefined'。
|
1月前
|
JavaScript
JS中call()、apply()、bind()改变this指向的原理
JS中call()、apply()、bind()改变this指向的原理
|
1月前
|
JavaScript 前端开发 API
Vue.js 深度解析:nextTick 原理与应用
Vue.js 深度解析:nextTick 原理与应用
|
2月前
|
缓存 JavaScript 前端开发
深入理解Vue.js 3中的响应式原理与使用技巧
【2月更文挑战第1天】Vue.js 3作为一款流行的前端框架,其核心特性之一是响应式数据绑定。本文将深入探讨Vue.js 3中的响应式原理,包括Reactivity API的设计思路和实现原理,并结合实际案例介绍在项目中如何有效地利用Vue.js 3的响应式特性。通过本文的学习,读者将更加全面地理解Vue.js 3的内部工作原理,提升在前端开发中的实践能力。
80 2