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]"
相关文章
|
2月前
|
自然语言处理 JavaScript 前端开发
探索JavaScript中的闭包:理解其原理与实际应用
探索JavaScript中的闭包:理解其原理与实际应用
20 0
|
2月前
|
JavaScript
JS数组增删方法的原理,使用原型定义
JS数组增删方法的原理,使用原型定义
|
4天前
|
缓存 前端开发 JavaScript
【JavaScript 技术专栏】JavaScript 前端路由实现原理
【4月更文挑战第30天】本文探讨了JavaScript前端路由在SPA中的重要性,阐述了其基本原理和实现方式,包括Hash路由和History路由。前端路由通过监听URL变化、匹配规则来动态切换内容,提升用户体验和交互性。同时,文章也提到了面临的SEO和页面缓存挑战,并通过电商应用案例分析实际应用。理解并掌握前端路由能助开发者打造更流畅的单页应用。
|
8天前
|
JavaScript 前端开发
js原生自调用函数原理
JavaScript中的IIFE(Immediately Invoked Function Expression)是定义后立即执行的函数表达式。它有两种实现方式:匿名函数表达式 `(function() { /* 函数体 */ })()` 和命名函数声明 `(function myFunction() { /* 函数体 */ })()`。IIFE提供封闭作用域,防止变量冲突,常用于创建私有作用域、封装代码和避免变量提升问题。执行后,IIFE内部的变量和函数会被销毁,除非被特意暴露。
|
9天前
|
前端开发 JavaScript
前端 富文本编辑器原理——从javascript、html、css开始入门(二)
前端 富文本编辑器原理——从javascript、html、css开始入门
21 0
前端 富文本编辑器原理——从javascript、html、css开始入门(二)
|
9天前
|
前端开发 JavaScript 索引
前端 富文本编辑器原理——从javascript、html、css开始入门(一)
前端 富文本编辑器原理——从javascript、html、css开始入门
20 0
|
12天前
|
前端开发 JavaScript 编译器
深入解析JavaScript中的异步编程:Promises与async/await的使用与原理
【4月更文挑战第22天】本文深入解析JavaScript异步编程,重点讨论Promises和async/await。Promises用于管理异步操作,有pending、fulfilled和rejected三种状态。通过.then()和.catch()处理结果,但可能导致回调地狱。async/await是ES2017的语法糖,使异步编程更直观,类似同步代码,通过事件循环和微任务队列实现。两者各有优势,适用于不同场景,能有效提升代码可读性和维护性。
|
23天前
|
JavaScript 前端开发
JS中的typeof
`typeof`操作符在JavaScript中用于检测变量的数据类型。然而,它并非总是完全准确,如:数组和null被错误地标记为'object',NAN是'number',Symbol是'function',而Array也是'function'。注意`undefined`返回'undefined'。
|
2月前
|
JavaScript
JS中call()、apply()、bind()改变this指向的原理
JS中call()、apply()、bind()改变this指向的原理
|
2月前
|
JavaScript 前端开发 API
Vue.js 深度解析:nextTick 原理与应用
Vue.js 深度解析:nextTick 原理与应用