更新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宏观执行。
`` ` ``
```javascript
#define JSVAL_IS_NULL(v) ((v) == JSVAL_NULL)
</code></pre>
<pre><code class="language-javascript line-numbers"><br /><br /></code></pre>
<p>```
这看起来像是很显而易见的bug,但是不要忘记,完成第一个JavaScript版本的时间很少。
看完两件小事
如果你觉得这篇文章对你挺有启发,我想请你帮我两个小忙:
- 把这篇文章分享给你的朋友 / 交流群,让更多的人看到,一起进步,一起成长!
- 关注公众号 「画漫画的程序员」,公众号后台回复「资源」 免费领取我精心整理的前端进阶资源教程
本文来源于网络,其版权属原作者所有,如有侵权,请与小编联系,谢谢!
转载请注明:文章转载自「 Js中文网 · 前端进阶资源教程 」https://www.javascriptc.com
链接:https://www.javascriptc.com/1935.html
原文链接:https://www.zcfy.cc/article/the-history-of-typeof-null