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中的闭包:原理与实战
【10月更文挑战第12天】深入理解JavaScript中的闭包:原理与实战
|
1月前
|
缓存 前端开发 JavaScript
JavaScript前端路由的实现原理及其在单页应用中的重要性,涵盖前端路由概念、基本原理、常见实现方式
本文深入解析了JavaScript前端路由的实现原理及其在单页应用中的重要性,涵盖前端路由概念、基本原理、常见实现方式(Hash路由和History路由)、优点及挑战,并通过实际案例分析,帮助开发者更好地理解和应用这一关键技术,提升用户体验。
74 1
|
1月前
|
监控 JavaScript 算法
深度剖析 Vue.js 响应式原理:从数据劫持到视图更新的全流程详解
本文深入解析Vue.js的响应式机制,从数据劫持到视图更新的全过程,详细讲解了其实现原理和运作流程。
|
1月前
|
JavaScript 前端开发
JavaScript 原型链的实现原理是什么?
JavaScript 原型链的实现原理是通过构造函数的`prototype`属性、对象的`__proto__`属性以及属性查找机制等相互配合,构建了一个从对象到`Object.prototype`的链式结构,实现了对象之间的继承、属性共享和动态扩展等功能,为 JavaScript 的面向对象编程提供了强大的支持。
|
1月前
|
前端开发 JavaScript
JS-instanceof 的实现原理
`instanceof` 运算符在前端 JavaScript 中用于检测对象的原型链是否包含指定构造函数的 `prototype` 属性。它通过遍历对象的原型链来实现。每个对象都有一个内部链接 `[[Prototype]]` 指向其原型对象,当访问属性或方法时,JavaScript 引擎会沿着原型链查找。`instanceof` 的具体实现是通过比较对象的原型链中的原型与构造函数的 `prototype` 属性,直到找到匹配的原型或到达原型链的顶端。示例代码展示了如何使用 `instanceof` 检查对象的继承关系。此外,`instanceof` 可用于验证继承关系和类型检查,支持多态性。
|
1月前
|
JavaScript 前端开发 API
Vue.js响应式原理深度解析:从Vue 2到Vue 3的演进
Vue.js响应式原理深度解析:从Vue 2到Vue 3的演进
57 0
|
2月前
|
前端开发 JavaScript
深入理解JavaScript中的事件循环(Event Loop):从原理到实践
【10月更文挑战第12天】 深入理解JavaScript中的事件循环(Event Loop):从原理到实践
45 1
|
2月前
|
数据采集 JavaScript 前端开发
JavaScript逆向爬虫——无限debugger的原理与绕过
JavaScript逆向爬虫——无限debugger的原理与绕过
115 2
|
2月前
|
自然语言处理 JavaScript 前端开发
深入理解JavaScript中的闭包:原理、应用与代码演示
【10月更文挑战第12天】深入理解JavaScript中的闭包:原理、应用与代码演示
|
2月前
|
自然语言处理 JavaScript 前端开发
深入理解JavaScript闭包:原理与应用
【10月更文挑战第11天】深入理解JavaScript闭包:原理与应用
25 0