【译】typeof null的前世今生

更新时间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源码 源码地址

原文地址:http://www.2ality.com/2013/10/typeof-null.html

时间: 2024-10-22 16:51:04

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

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

1997 年,IE 4.0 发布,带来的众多新特性中有一个对未来“影响深远”的 DOM API:document.all.在随后的 6 年里,IE 的市场占有率越来越高,直到 2003 年的 95%. 在这段时间里,产生了两种成千上万的页面.第一种:IE only 的页面,由于超高的市场占有率,开发人员觉得根本不需要考虑兼容性,于是直接使用 document.all,比如: document.all(foo).style.visibility = "visible" 甚至很多网站直接在

JavaScript typeof, null, 和 undefined

JavaScript 数据类型 在 JavaScript 中有 5 种不同的数据类型: string number boolean object function 3 种对象类型: Object Date Array 2 个不包含任何值的数据类型: null undefined 例子: typeof "John"                 // 返回 string typeof 3.14                   // 返回 numbertypeof NaN      

JavaScript基础学习-- typeof,null,undefined

null 在 JavaScript 中 null 表示 "什么都没有". null是一个只有一个值的特殊类型.表示一个空对象引用. var person = {firstName:"John", lastName:"Doe", age:50, eyeColor:"blue"}; var person = null; document.getElementById("demo").innerHTML = ty

typeof(null) ==>object null instanceof Object ==>false

typeof(null) ==>object    null  instanceof Object ==>false   typeof(null) === Objectfalse 原文地址:https://www.cnblogs.com/oklfx/p/8379544.html

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

java 中的 null:既是对象,又不是对象,史称「薛定谔的对象」. typeof null==='object';  ..//true null instanceof Object  //false nullinstanceofObject===false 而 null instanceof null 会抛出异常: UncaughtTypeError:Right-hand side of 'instanceof'isnotan object 这是一个历史遗留下来的 feature(or bu

typeof null ======》"object"

都知道typeof null的值是object,那么为什么typeof null 的值是object呢. <你不知道的javascript>中写到: 原理是这样的,不同的对象在底层都表示为二进制,在jsvascript中要是二进制前三位都是0的话就表示对象,而null的二进制都是0,那么前三位自然也是0,就被认为是object,所以typeof null 返回的是object. 原文地址:https://www.cnblogs.com/yxfboke/p/11445722.html

JavaScript数据类型(一)——typeof操作符、Boolean、Null和Undefined

一.JavaScript数据类型 JavaScript的数据类型分为以下几类: 五种简单数据类型:Undefined,Null,Boolean,String,Number. 一种复杂数据类型:Object. 二.typeof操作符 下面将分几个小短篇对其进行总结,在总结之前,先认识一个非常有用的操作符——typeof. typeof操作符是用来检测JavaScript数据类型的操作符,它会返回上面的数据类型之一.但是其中有一个特例,那就是Null的数据类型会返回Object,即typeof Nu

typeof与instanceof比较+undefined与null各种值的相互比较

1.typeof:返回一个字符串 根据typeof判断对象 表达式 返回值 typeof undefined 'undefined' typeof true 'boolean' typeof 123 'number' typeof "abc" 'string' typeof function() {} 'function' typeof {} 'object' typeof [] 'object' typeof null 'object' function f(...args) { c

Javascript中的typeof和instanceof

typeof 是一元操作符,而instanceof是二元操作符: typeof 操作的是一个变量,而instanceof前面是一个变量,后面是一个类型: typeof 返回的是一个字符串,而instanceof 返回的是一个布尔值. 1.typeof() http://www.cnblogs.com/jikey/archive/2010/05/05/1728337.html typeof 是一个一元运算,放在一个运算数之前,运算数可以是任意类型.它返回值是一个字符串,该字符串说明运算数的类型.,