我的翻译小站:https://www.zcfy.cc/article/the-history-of-typeof-null

翻译原文链接:http://2ality.com/2013/10/typeof-null.html

更新2013-11-05:我发现用C语言能够很好的解释为什么typeof null 结果是'object'。

在JavaScript中,typeof null 是 'object',它错误地将null认为是对象(其实它不是,它是一个原始的值,详情可查询 categorizing values )。这是一个bug,不幸地是无法被修复,因为它会破坏现有的代码。让我们一起来探索一下这个bug的历史吧。

从JavaScript第一个版本,“typeof null” 就是一个bug坑。这个版本里,值被以32位单位保存, 包括小类型标签(1-3位)和实际数据的值。这种类型标签被以更低的单位保存。这里有其中的五个:

  • 000: 对象。数据是对对象的引用。

  • 1: 整型。数据是31位带符号整数。

  • 010: 浮点型。数据是对浮点数据的引用。

  • 100: 字符。 数据是对字符串类型的引用。

  • 110: boolean. 数据是boolean。

也就是说,最低位是任意一个,那么类型标签是只有1位长。或者是0,那么类型标签的长度为3位,就会为4种类型提供了额外的2位。

有2种值是特殊的:

  • undefined (JSVAL_VOID)是整数−(2^30)(数值在整数范围外)。

  • null (JSVAL_NULL) 是代码空指针。或者:一个对象类型标签加上一个为零的引用。

现在很明显,为什么 typeof null 被认为是对象:它检查了它的类型标签,类型标签说是“object”。下面是 typeof的引擎代码。

  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)) { // (1)
type = JSTYPE_VOID;
} else if (JSVAL_IS_OBJECT(v)) { // (2)
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) // (3,4)
: ops->call != 0)) { // (3)
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;
}

执行步骤如上代码所示:

  • 在(1)中,引擎首先检查值v 是否是undefined (VOID)。比较两个值是否相等。

    #define JSVAL_IS_VOID(v)  ((v) == JSVAL_VOID)
  • 接下来(2)是检查值是否有对象标签。如果它是可调用的(3)或者它的内部属性[[Class][]将它标记为一个函数(4)那么' v '就是一个函数。否则,它就是一个对象。这是' typeof null '生成的结果。

  • 接下来是检查数字,字符串和boolean。这里没有给null明确的检查,它可以由C宏观执行。

       #define JSVAL_IS_NULL(v)  ((v) == JSVAL_NULL)

这看起来像是很显而易见的bug,但是不要忘记,完成第一个JavaScript版本的时间很少。

致敬: 感谢Tom Schuster (@evilpies指出JavaScript原始代码.


作者:婷风

出处:https://www.cnblogs.com/jtjds/p/10413480.html

如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!欢迎各位转载,但是未经作者本人同意

转载文章之后必须在 文章页面明显位置给出作者和原文连接否则保留追究法律责任的权利。

【翻译】追溯“typeof null”的历史的更多相关文章

  1. V8 的 typeof null 返回 "undefined" 的 bug 是怎么回事

    1997 年,IE 4.0 发布,带来的众多新特性中有一个对未来“影响深远”的 DOM API:document.all.在随后的 6 年里,IE 的市场占有率越来越高,直到 2003 年的 95%. ...

  2. 在 JavaScript 中为什么 typeof null 的结果是 object?

    java 中的 null:既是对象,又不是对象,史称「薛定谔的对象」. typeof null==='object';  ..//true null instanceof Object  //fals ...

  3. 你真的知道typeof null的结果为什么是‘object‘吗?

    到目前为止,ECMAScript 标准中定义了8种数据类型,它们分别是Undefined.Null.Number.Boolean.String.Symbol.BigInt.Object. 为了判断变量 ...

  4. JavaScript数据类型 typeof, null, 和 undefined

    JavaScript 数据类型 在 JavaScript 中有 5 种不同的数据类型: string number boolean object function 3 种对象类型: Object Da ...

  5. JavaScript typeof, null, 和 undefined

    typeof 操作符 你可以使用 typeof 操作符来检测变量的数据类型. 实例 typeof "John"                // 返回 string typeof ...

  6. 【译】typeof null的前世今生

        更新时间2013-11-05:为了更好的解释为什么typeof null的结果是object,我看了一下C代码的实现(译者注:Javascript源码).       在Javascript语 ...

  7. typeof null 为什么等于 object?

    之前只知道typeof null = object,但是却从来不知道是为什么.最新查阅资料的时候,看到了这个原理,记录下来,方便自己以后查看. 原理是这样的,不同的对象在底层都表示为二进制,在 Jav ...

  8. null与对象的复杂关系(typeof null的结果是object的原因)

    原文 简书原文:https://www.jianshu.com/p/c1608452d056 前言 对象是 JavaScript 的基础.在 JavaScript 中一共有六种主要类型(术语是“语言类 ...

  9. 你真的懂JavaScript基础类型吗

    夯实Javascript基础. 基本类型有六种: null,undefined,boolean,number,string,symbol. 基本类型的值是保存在栈内存中的简单数据段 基础类型特性 基础 ...

随机推荐

  1. Axel与Wget下载工具

    Axel工具是linux下的http/ftp中强大下载工具,支持多线程和断点续传下载.且可以从多个地址或者从一个地址的多个连接来下载同一个文件. 常用的选项: [root@wjoyxt ~]# axe ...

  2. delphi 图片加水印源代码

    unit UWaterMark; interface uses {$IFNDEF DELPHIXE2ANDUP} windows,SysUtils,classes,graphics,Gdiplus; ...

  3. Game2048

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  4. hibernate最佳实践

    1.数据量巨大,性能要求高,hibernate由于在ORM映射中对系统资源消耗也比较高,所以不适合 2.hibernate适合:逻辑复杂,数据量不大. 3.sessionFactory的创建非常消耗资 ...

  5. 删除临时表空间ora-25152错误

    删除临时表空间,或者收缩临时表空间经常会出现表空间占用等情况. 下面我们就对这种情况进行处理, 首先查找被锁的sid: SELECT a.INST_ID,b.TABLESPACE , b.segfil ...

  6. iperf——网络性能测试工具

    一.前言 工作中遇到需要测试Linux服务器网卡占用率的场景,查阅资料后,发现iperf是一款合适的网络测速工具. 下面讲解一下如何使用iperf做网络性能测试. 二.基础知识 先补充一些基础知识: ...

  7. 为什么JAVA要提供 wait/notify 机制?是为了避免轮询带来的性能损失

    wait/notify  机制是为了避免轮询带来的性能损失. 为了说清道理,我们用“图书馆借书”这个经典例子来作解释. 一本书同时只能借给一个人.现在有一本书,图书馆已经把这本书借了张三. 在简单的s ...

  8. hdoj2859(矩阵DP)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2859 思路: 第一次碰到这种矩阵上的DP题,想了半天也没想明白.本来想用子矩阵的左上角坐标和右下角坐标 ...

  9. hdoj1257(DP-LIS/贪心)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1257 方法1--贪心: 定义一个数组f[30005],由于题目没给数据量大小,故为了保险,开到最大(高 ...

  10. LIS问题(DP解法)---poj1631

    题目链接:http://poj.org/problem?id=1631 这个题题目有些难看懂hhh,但实质就是求LIS--longest increasing sequence. 以下介绍LIS的解法 ...