你真的知道typeof null的结果为什么是‘object‘吗?
到目前为止,ECMAScript 标准中定义了8种数据类型,它们分别是Undefined、Null、Number、Boolean、String、Symbol、BigInt、Object。
为了判断变量的数据类型,JavaScript还提供了typeof操作符。
数据类型中的值通过typeof操作符操作过后输出的值对应表格:
| 数据类型 | 值 | 结果 |
|---|---|---|
| Undefined | undefined | 'undefined' |
| Null | null | 'object' |
| Number | 1、1.0、NaN、Infinity | 'number' |
| Boolean | true、false | 'boolean' |
| String | '' 、'abc' | 'string' |
| Symbol | Symbol()、Symbol('123') | 'symbol' |
| BigInt | 0n、1n | 'bigint' |
| Object | {}、[] | 'object' |
| Object | function(){} | 'function' |
通过观察,我们可以发现一个问题——typeof操作符错误的将一个原始类型值null判断为object
typeof null === 'object'//true
这将导致typeof x === 'object'时,x还有可能是null
这个问题的产生可以追溯到JavaScript的第一个版本[1],在这个版本中,单个值在栈中占用32位的存储单元,而这32位的存储单元又可以划分为类型标签(1-3位)和实际数据,类型标签存储于低位中,具体可以分成5种:
(1)

如图[2],当第0位、第1位和第2位皆为0时,typeof判断类型为'object';
(2)

如图[2:1],当第0位为1时,typeof判断类型为'number(整数)';
(3)

如图[2:2],当第0位与第2位皆为0,而第1位为1时,typeof判断类型为'number(浮点数)';
(4)

如图[2:3],当第0位与第1位皆为0,而第2位为1时,typeof判断类型为'string';
(5)

如图[2:4],当第1位与第2位皆为1,而第0位为0时,typeof判断类型为'boolean';
此外还有两种特殊情况:
undefined:整数−2^30 (整数范围之外的数字)
null:第0位到第31位皆为0(正好满足当第0位、第1位和第2位皆为0时,typeof判断类型为'object'的条件)
下面的代码更好的说明了这个问题(来源):
JS_PUBLIC_API(JSType)
JS_TypeOfValue(JSContext *cx, jsval v)
{
JSType type = JSTYPE_VOID;
JSObject *obj;
JSObjectOps *ops;
JSClass *clasp;
CHECK_REQUEST(cx);
if (JSVAL_IS_VOID(v)) {
type = JSTYPE_VOID;
} else if (JSVAL_IS_OBJECT(v)) {
obj = JSVAL_TO_OBJECT(v);
if (obj &&
(ops = obj->map->ops,
ops == &js_ObjectOps
? (clasp = OBJ_GET_CLASS(cx, obj),
clasp->call || clasp == &js_FunctionClass)
: ops->call != 0)) {
type = JSTYPE_FUNCTION;
} else {
type = JSTYPE_OBJECT;
}
} else if (JSVAL_IS_NUMBER(v)) {
type = JSTYPE_NUMBER;
} else if (JSVAL_IS_STRING(v)) {
type = JSTYPE_STRING;
} else if (JSVAL_IS_BOOLEAN(v)) {
type = JSTYPE_BOOLEAN;
}
return type;
}
正因如此,导致typeof null === 'object'为true。
你真的知道typeof null的结果为什么是‘object‘吗?的更多相关文章
- V8 的 typeof null 返回 "undefined" 的 bug 是怎么回事
1997 年,IE 4.0 发布,带来的众多新特性中有一个对未来“影响深远”的 DOM API:document.all.在随后的 6 年里,IE 的市场占有率越来越高,直到 2003 年的 95%. ...
- JavaScript数据类型 typeof, null, 和 undefined
JavaScript 数据类型 在 JavaScript 中有 5 种不同的数据类型: string number boolean object function 3 种对象类型: Object Da ...
- JavaScript typeof, null, 和 undefined
typeof 操作符 你可以使用 typeof 操作符来检测变量的数据类型. 实例 typeof "John" // 返回 string typeof ...
- 【译】typeof null的前世今生
更新时间2013-11-05:为了更好的解释为什么typeof null的结果是object,我看了一下C代码的实现(译者注:Javascript源码). 在Javascript语 ...
- 【翻译】追溯“typeof null”的历史
我的翻译小站:https://www.zcfy.cc/article/the-history-of-typeof-null 翻译原文链接:http://2ality.com/2013/10/typeo ...
- typeof null 为什么等于 object?
之前只知道typeof null = object,但是却从来不知道是为什么.最新查阅资料的时候,看到了这个原理,记录下来,方便自己以后查看. 原理是这样的,不同的对象在底层都表示为二进制,在 Jav ...
- null与对象的复杂关系(typeof null的结果是object的原因)
原文 简书原文:https://www.jianshu.com/p/c1608452d056 前言 对象是 JavaScript 的基础.在 JavaScript 中一共有六种主要类型(术语是“语言类 ...
- 在 JavaScript 中为什么 typeof null 的结果是 object?
java 中的 null:既是对象,又不是对象,史称「薛定谔的对象」. typeof null==='object'; ..//true null instanceof Object //fals ...
- JS四种判断数据类型的方法:typeof、instanceof、constructor、Object.prototype.toString.call()
1.typeof 1 console.log(typeof ""); //string 2 console.log(typeof 1); //number 3 console.lo ...
随机推荐
- 七:SpringBoot-集成Redis数据库,实现缓存管理
SpringBoot-集成Redis数据库,实现缓存管理 1.SpringBoot集成Redis 1.1 核心依赖 1.2 配置文件 1.3 简单测试案例 1.4 自定义序列化配置 1.5 序列化测试 ...
- KVM(虚拟机的迁移)
- Hiho1422 Harmonic Matrix Counter (高斯消元)
16年北京站A题 真的难啊.. 题意: 定义和谐矩阵 就是每个元素和上下左右的xor值=0 输出一个超大数 然后最多800个询问 求字典序第k小的和谐矩阵 x y位置上的数 题解: 首先这个超大数的范 ...
- HDU5589 Tree【分块 01字典树】
HDU5589 Tree 题意: 给出一棵\(N\)个点的树,每条边有边权,每次询问下标为\([L,R]\)区间内的点能选出多少点对,点对之间的路径上的边权异或和大于\(M\) 题解: 对于两点\(u ...
- Codeforces Round #631 div1C(或者div2E) Drazil Likes Heap 题解
题目链接:https://codeforces.com/contest/1329/problem/C 或者:https://codeforces.com/contest/1330/problem/E ...
- G - Can you answer these queries? & N - 花神游历各国
A lot of battleships of evil are arranged in a line before the battle. Our commander decides to us ...
- hdu4507吉哥系列故事——恨7不成妻 (数位dp)
Problem Description 单身! 依然单身! 吉哥依然单身! DS级码农吉哥依然单身! 所以,他生平最恨情人节,不管是214还是77,他都讨厌! 吉哥观察了214和77这两个数,发现: ...
- hdu 6835 Divisibility 思维
题意: 给你一个10进制的b和x,对于任意的一个b进制的y.如果y每一位的和可以被x整除,且y可以被x整除:或者如果y每一位的和不可以被x整除,且y不可以被x整除.那么就输出T.否则输出F 题解: 代 ...
- CF1400-C. Binary String Reconstruction
CF1400-C. Binary String Reconstruction 题意: 对于一个二进制字符串\(s\),以及一个给定的\(x\),你可以通过一下操作来得到字符串\(w\): 对于字符串\ ...
- 【Azure 微服务】基于已经存在的虚拟网络(VNET)及子网创建新的Service Fabric并且为所有节点配置自定义DNS服务
问题描述 创建新的Service Fabric集群,可以通过门户,Powershell命令,或者是ARM模板.但是通过门户和PowerShell命令时,创建的SF集群都会自动新建一个虚拟网络而无法使用 ...