【译】谈谈“typeof null为object”这一bug的由来

栏目: C · 发布时间: 5年前

内容简介:很多前端初级开发者也许并不深究typeof null为何为Object?想更深地了解这一bug的由来,可以参阅Dr. Axel Rauschmayer关于"typeof null"的历史这篇文章。原文链接:我看了下C语言关于

很多前端初级开发者也许并不深究typeof null为何为Object?想更深地了解这一bug的由来,可以参阅Dr. Axel Rauschmayer关于"typeof null"的历史这篇文章。

原文链接: www.2ality.com/2013/10/typ…

我看了下 C语言 关于 typeof 的规范,它对于 typeof null 为何结果是’ object ’有更好的解释。

在JavaScript中, typeof null 的结果是' Object ',它错误地暗示 null 是一个对象,实际上它是一个原始值。我在上一篇文章也提到了这是JS的一大bug,不幸的是这并不能解决,因为这将破坏现有规范,接下来解释下这个bug的历史。

typeof null ”的错误从JavaScripts第一个版本开始就已经存在了。在这个版本,值以32位为单位存储,由小型标签(1-3位)和值的实际数据组成。类型标签存储在单元的低位中。 其中有五种:

object
int
double
string
boolean

也就是说,最低位是1,然后类型标签只有1位长,即 int 型。 或者最低位为0,那么类型标签的长度为3位,为其余4种类型提供了两个附加位。

但有2个值是特殊的:

undefined
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)引擎首先检测值是否是 undefined (VOID),它通过 == 做了这样的比较:
#define JSVAL_IS_VOID(v)  ((v) == JSVAL_VOID)
复制代码
  • 下一个(2)是检测该值是否具有 object type 。如果它可使用 call 被调用(3)或其存在内部属性 [[Class]] 标记为函数(4),则v是函数。 否则,它是一个对象。 这是由 typeof null 生成的结果。

  • 后续检查是针对 numberstringboolean ,甚至没有明确检查 null 。这可以由以下C语言宏执行。

#define JSVAL_IS_NULL(v)  ((v) == JSVAL_NULL)`  
复制代码

这看似是一个非常明显的bug,但不要忘记,第一个版本的JavaScript完成只用了极少的时间,具体可以看看JavaScript的诞生。

如果觉得文章对你有些许帮助,欢迎在 我的GitHub博客 点赞和关注,感激不尽!


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

算法引论

算法引论

[美]Udi Manber / 黄林鹏、谢瑾奎、陆首博、等 / 电子工业出版社 / 2005-9-1 / 35.00元

本书是国际算法大师乌迪·曼博(Udi Manber)博士撰写的一本享有盛誉的著作。全书共分12章:第1章到第4章为介绍性内容,涉及数学归纳法、算法分析、数据结构等内容;第5章提出了与归纳证明进行类比的算法设计思想;第6章到第9章分别给出了4个领域的算法,如序列和集合的算法、图算法、几何算法、代数和数值算法;第10章涉及归约,也是第11章的序幕,而后者涉及NP完全问题;第12章则介绍了并行算法;最后......一起来看看 《算法引论》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

SHA 加密
SHA 加密

SHA 加密工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具