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

javascript 中的 null:既是对象,又不是对象,史称「薛定谔的对象」。

  
    
    
    
    
  1. typeof null === 'object';

  2. null instanceof Object === false

  
    
    
    
    
  1. null instanceof null

会抛出异常:

  
    
    
    
    
  1. Uncaught TypeError: Right-hand side of 'instanceof' is not an object


这是一个历史遗留下来的 feature(or bug?),The history of “typeof null”

在 javascript 的最初版本中,使用的 32 位系统,为了性能考虑使用低位存储了变量的类型信息:

  • 000:对象

  • 1:整数

  • 010:浮点数

  • 100:字符串

  • 110:布尔

有 2 个值比较特殊:

  • undefined:用 -2^{30} (−2^30)表示。

  • null:对应机器码的 NULL 指针,一般是全零。

在第一版的 javascript 实现中,判断类型的代码是这么写的:

  
    
    
    
    
  1. if (JSVAL_IS_VOID(v)) {  // (1)

  2.    type = JSTYPE_VOID;

  3. } else if (JSVAL_IS_OBJECT(v)) {  // (2)

  4.    obj = JSVAL_TO_OBJECT(v);

  5.    if (obj &&

  6.        (ops = obj->map->ops,

  7.            ops == &js_ObjectOps

  8.            ? (clasp = OBJ_GET_CLASS(cx, obj),

  9.            clasp->call || clasp == &js_FunctionClass) // (3,4)

  10.            : ops->call != 0)) {  // (3)

  11.        type = JSTYPE_FUNCTION;

  12.    } else {

  13.        type = JSTYPE_OBJECT;

  14.    }

  15. } else if (JSVAL_IS_NUMBER(v)) {

  16.    type = JSTYPE_NUMBER;

  17. } else if (JSVAL_IS_STRING(v)) {

  18.    type = JSTYPE_STRING;

  19. } else if (JSVAL_IS_BOOLEAN(v)) {

  20.    type = JSTYPE_BOOLEAN;

  21. }

javascript

(1):判断是否为 undefined

(2):如果不是 undefined,判断是否为对象

(3):如果不是对象,判断是否为数字

(4):。。。

这样一来, null 就出了一个 bug。根据 type tags 信息,低位是 000,因此 null 被判断成了一个对象。这就是为什么 typeofnull 的返回值是 "object"

关于 null 的类型在 MDN 文档中也有简单的描述:typeof - javascript | MDN

在 ES6 中曾有关于修复此 bug 的提议,提议中称应该让 typeofnull==='null' http://wiki.ecmascript.org/doku.php?id=harmony:typeof_null 但是该提议被无情的否决了,自此 typeofnull 终于不再是一个 bug,而是一个 feature,并且永远不会被修复。


你可能感兴趣的:(在 JavaScript 中为什么 typeof null 的结果是 object?)