更新时间2013-11-05:为了更好的解释为什么typeof null的结果是object,我看了一下C代码的实现(译者注:Javascript源码)。
 
    在Javascript语言中,typeof null的结果是object。这样就会错误的认为null是一个对象(事实上,它不是一个对象,它是原始值,详细的说明可以看我的发布的博客 Javascript中的数据类型 )。很不幸,它是一个不能修复的bug,因为修复后会破坏掉现有的代码。那么。让我们探索一下这个bug的起源吧。
 
    这个bug是第一版Javascript留下来的。在这个版本,数值是以32字节存储的,由标志位(1~3个字节)和数值组成。标志位存储的是低位的数据。这里有五种标志位:
  • 000:对象,数据是对象的应用。
  • 1:整型,数据是31位带符号整数。
  • 010:双精度类型,数据是双精度数字。
  • 100:字符串,数据是字符串。
  • 110:布尔类型,数据是布尔值。
    最低位有一位,那么标志位只有一个1字节长度;或者是零位,标志位有3个字节长度,多出两个了字节,一共多出四种类型。
 
    有两个特殊的数值:
  • 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),代码首先会检查数值是不是undefined(VOD)。是通过比较值:
 #define JSVAL_IS_VOID(v)  ((v) == JSVAL_VOID)
//译者注:比较值是否与undefined值相等
  • 注释(2),判断值是否有对象的标志位。如果它是可调用的,或者说通过内部属性[[Class]]可以表明它是一个函数。否者它就是一个对象。这也就是typeof null的执行结果。
  • 随后是针对数字、字符串和布尔值的检测。这里并没有明确的检测null,源码中本应该有这样的实现:
 #define JSVAL_IS_NULL(v)  ((v) == JSVAL_NULL)
//译者注:本身应该存在一个类似检测undefined一样的方法,来检测null,但是事实证明它并没有
 
    这看起来像是一个很明显的bug,但是不要忘了Javascript的第一个版本花费了很少的时间完成的。
 
    感谢:感谢 Tom Schuster (@evilpies)告诉我Javascript源码 源码地址
 
 
 
 
 

【译】typeof null的前世今生的更多相关文章

  1. typeof null 为什么等于 object?

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

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

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

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

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

  4. JavaScript typeof, null, 和 undefined

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

  5. 【翻译】追溯“typeof null”的历史

    我的翻译小站:https://www.zcfy.cc/article/the-history-of-typeof-null 翻译原文链接:http://2ality.com/2013/10/typeo ...

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

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

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

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

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

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

  9. 走进javascript——类型

    ECMAScript语言类型对应于使用ECMAScript语言的ECMAScript程序员直接操作的值.ECMAScript语言类型有以下几种Undefined,Null,Boolean,String ...

随机推荐

  1. Java向上转型注意事项

    继承.接口:Java子类中如果含有父类中不包含的变量与方法,子类对象向上转型时就是丢失这些变量和方法. interface SuperClass{ int i = 2; void f() ; } cl ...

  2. CSS常用操作-图片

    index.html <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> &l ...

  3. ajax弹出窗口

    提取自ZCMS的弹出框: 代替window.open.window.alert.window.confirm:提供良好的用户体验: 水晶质感,设计细腻,外观漂亮: 兼容ie6/7/8.firefox2 ...

  4. 採集和输出 DeckLink Studio 4K

  5. Hadoop 开源调度系统zeus(二)

    紧跟之前Hadoop 开源调度系统zeus(一) 本节主要介绍一下zeus的架构: 先给一个zeus的架构图 无论Master还是Worker都有一套WEB UI,无论从哪个上面去看,看到的结果都是一 ...

  6. Java当中的运算符

    一.关于Java当中运算符的分类 算术运算符:+,-,*,/.%(是取余运算符读莫).++.-- 关系运算符:>.<.>=.<=.!=(不等).==(等于) 布尔运算符:!(非 ...

  7. redisi配置安装

    一.单机配置 http://www.codeceo.com/article/centos-redis-setup.html 二.测试安装情况 http://blog.sina.com.cn/s/blo ...

  8. 初探R语言——R语言笔记

    R语言使用 <-  赋值 # 作为注释符号 c()函数用于作为向量赋值,例如age<-c(1,2,3,4,5) mean()用于求向量的平均值 sd()求向量的标准差 cor(a,b)求a ...

  9. ProgressBar( 进度条) 组件

    一. 加载方式 //class 加载方式<div class="easyui-progressbar"data-options="value:60" st ...

  10. Activity一共有以下四种launchMode

    1. standard: 无论什么情况都会生成一个新的Activity实例,并且放于栈顶. 2. singleTop:如果Activity纯在但是不位于栈顶,就重新生成一个Activity实例. 3. ...