为什么JavaScript里面typeof(null)的值是"object"?

在JavaScript中,typeof null是'object',它不正确地表明null是一个对象,这是一个错误,不幸的是无法修复,因为它会破坏现有的代码。我们来探讨这个bug的历史。

“typeof null”错误是JavaScript第一个版本的补遗。在这个版本中,值以32位为单位存储,其中包含一个小型标记(1-3位)和实际的数据值。类型标签存储在单元的低位中。其中有五个:

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

1:int        数据是一个31位有符号整数。

010:double        数据是对双浮点数的引用。

100:string        数据是对字符串的引用。

110:boolean        数据是一个布尔值。

也就是说,最低位是一个,然后类型标签只有一个位长。或者它是零,那么类型标签的长度是三位,为四种类型提供两个附加位。

两个值是特殊的:

未定义(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是否是未定义的(VOID)。该检查通过等于比较值来执行:

    #define JSVAL_IS_VOID(v)((v)== JSVAL_VOID)

下一个检查(2)是该值是否具有对象标签。如果它另外是可调用的(3)或其内部属性[[Class]]将其标记为函数(4),则v是函数。否则,它是一个对象。这是由typeof null产生的结果。

随后的检查是针对数字,字符串和布尔值。甚至没有对null进行明确的检查,这可以由以下C宏执行。

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

这可能看起来像一个非常明显的错误,但不要忘记,完成JavaScript的第一个版本的时间非常短。



 在程序中如何判断变量是否为null。

    以下是不正确的方法: 

1、var exp = null;

    if (exp == null)

    {

        alert("is null");

    }

    exp 为 undefined 时,也会得到与 null 相同的结果,虽然 null 和 undefined 不一样。

    注意:要同时判断 null 和 undefined 时可使用本法。

2、var exp = null;

    if (!exp)

    {

        alert("is null");

    }

    如果 exp 为 undefined,或数字零,或 false,也会得到与 null 相同的结果,虽然 null 和二者不一样。

    注意:要同时判断 null、undefined、数字零、false 时可使用本法。

3、var exp = null;

    if (typeof exp == "null")

    {

        alert("is null");

    }

    为了向下兼容,exp 为 null 时,typeof null 总返回 object,所以不能这样判断。

4、var exp = null;

    if (isNull(exp))

    {

        alert("is null");

    }

    VBScript 中有 IsNull 这个函数,但 JavaScript 中没有。

--------------------------------------------------------------------------------

    以下是正确的方法: 

1、var exp = null;

    if (!exp && typeof exp != "undefined" && exp != 0)

    {

        alert("is null");

    }

    typeof exp != "undefined" 排除了 undefined; 

    exp != 0 排除了数字零和 false。

    更简单的正确的方法:


2、var exp = null;

    if (exp === null)

    {

        alert("is null");

    }

--------------------------------------------------------------------------------

尽管如此,我们在 DOM 应用中,一般只需要用 (!exp) 来判断就可以了,因为 DOM 应用中,可能返回 null,可能返回 undefined,如果具体判断 null 还是 undefined 会使程序过于复杂。

参考文章:The history of “typeof null”

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,544评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,430评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,764评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,193评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,216评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,182评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,063评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,917评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,329评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,543评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,722评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,425评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,019评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,671评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,825评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,729评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,614评论 2 353

推荐阅读更多精彩内容

  • "use strict";function _classCallCheck(e,t){if(!(e instanc...
    久些阅读 2,029评论 0 2
  • 第2章 基本语法 2.1 概述 基本句法和变量 语句 JavaScript程序的执行单位为行(line),也就是一...
    悟名先生阅读 4,148评论 0 13
  • Lua 5.1 参考手册 by Roberto Ierusalimschy, Luiz Henrique de F...
    苏黎九歌阅读 13,788评论 0 38
  • 假如你现在能爱,就请好好地爱着,因为你不知道惊喜与意外那一个先来。 一 早上一丝明媚的阳光,穿过凌美窗前的那棵茂密...
    右半边爱情阅读 768评论 4 4
  • 碌碡赋闲 黄牛退休 连脱粒机也因落后而感到蒙羞 收割机生龙活虎,有好大的胃口 偌大一片麦子,瞬间全被吞入腹中 它象...
    泰山寒梅阅读 302评论 7 17