javascript中的null,对象系统还是非对象系统?
1.一直以来的认知
在我学习js的过程中,爱民老师的绿皮书里将js的类型系统分成了两类:

其一是元类型系统:由typeof运算来检测
其二是对象类型系统:是元类型的object的一个分支
而null这个关键字也被归类到了对象类型系统里面了:
- 是属于对象系统的
- 对象是空值
所以,当我们使用typeof去考察Null的话,会返回给我们"object"。
如果去用for(... in null)的方式试图去枚举Null里面的属性的时候。ES5会先行判断null和undefined,如果是这两个值的话,不会去执行循环体。
而我认为这一切都是null既无属性也无方法导致的。而且null也并无原型,也并不是Object()构造器或者其子类实例而来的。
而我是c#出身的前端,我觉得将null归类到对象系统里面是一个不错的选择!
2.《你不知道的js》里面怎么说的?
当我看到第三章的对象的时候,里面有这样一段话
null 有时会被当作一种对象类型,但是这其实只是语言本身的一个 bug,即对 null 执行
typeof null 时会返回字符串 "object"。实际上,null 本身是基本类型
看到这里,完全颠覆我的认知啊!

按照“u dot know”里面的划分的话其实也是书里面很常见的一种划分方式。高程3中就是这样来划分js的类型系统的。但是,因为我觉得爱民老师这样的划分方式也没什么不妥。一切都是看待问题的角度不同导致的。而爱民老师将null归类到对象类型里面去,因为在js中除了undefined之外的都是对象。
而“u dot know”直接耳提面命的告诉我:你一直理解的js类型系统,是错的!
//'u dot kown'里的注解
注 1:原理是这样的,不同的对象在底层都表示为二进制,在 JavaScript 中二进制前三位都为 0 的话会被判
断为 object 类型,null 的二进制表示是全 0,自然前三位也是 0,所以执行 typeof 时会返回“object”。
3.到底怎么理解?
因为有了疑虑,所以我们要去探查真相!
终于,贺老给了我们一个很好的回答!
hax主要说了以下几个点:
- 爱民老师是按照自己的理解来分类的,而不是按照ECMA来照本宣科的,况且他写书的时候ES5/ES6还没有出来,而ES5之前的ES规范其实都写得比较烂
- 现在比较普遍的认知是,typeof null返回“object”是一个历史错误(JS的发明者Brendan Eich自己也是这样说的),只是因为要保持语言的兼容性而维持至今。从ES5制定开始就有动议将typeof null改为返回“null”(如启动node加上“--harmony_typeof”参数,即是如此),但是当前ES6标准草案仍然维持了原样。
- 按照爱民的意见,也可在某种程度上理解为null实为object类型的一个特殊值。在诸如Java这样的语言中,一个变量若是primitive类型,均不可赋以null值,而若是 object,则均可赋以null值。因为在理解上来说,null实际是引用(reference)的特殊值(表示没有指向任何实际对象)
- ECMA是如何划分概念,主要是依据ECMA的逻辑,而不是其他标准。所以从ECMA的逻辑看,类型系统是这样划分的,也是合理的
4.结论
javascript中的null,对象系统还是非对象系统?的更多相关文章
- 浅谈JavaScript中的null和undefined
浅谈JavaScript中的null和undefined null null是JavaScript中的关键字,表示一个特殊值,常用来描述"空值". 对null进行typeof类型运 ...
- 区别Javascript中的Null与Undefined
在JavaScript中存在这样两种原始类型:Null与Undefined.这两种类型常常会使JavaScript的开发人员产生疑惑,在什么时候是Null,什么时候又是Undefined? Undef ...
- JavaScript中对null和undefined的理解
前沿: 今天工作中遇到了监视一个变量是undefined,结果判断写的是==null 返回值是true,这个结果引起了我对这两个东西的兴趣. 查询了相关的文章理解并测试了.发现有以下特点: 1.广义上 ...
- null的坑 和 比较运算符、相等运算符的隐式转换问题 (在javascript中,null>=0 为真,null<=0 为真,null==0却为假,null到底是什么?)
null在关系运算中的坑 & 关系运算符的隐式转换问题 注意: 比较运算符 和 相等运算符 的 ECMAscript 语法实现不同. 比较运算符 和 相等运算符 对数据进行了隐式转换, 相当于 ...
- JavaScript中的 原型 property 构造函数 和实例对象之间的关系
1 为什么要使用原型? /* * javascript当中 原型 prototype 对象 * * */ //首先引入 prototype的意义,为什么要使用这个对象 //先来写一个构造函数的面向对象 ...
- javascript中使用new与不使用实例化对象的区别
我们先来看个实例 function Me(name,age,job){ this.name = name; this.age = age; this.job = job; } 请问这以下两种实例化对象 ...
- JavaScript中推断一个对象是否为"空对象”
JavaScript中推断一个对象是否为"空对象" 这里指的"空对象"是类似于:{ } 和 new Object() 这种. 详细的代码实现和原理例如以下: / ...
- Javascript中的null和 undefined
Javascript Undefined vs NULL Many a times we often get confused on whats the difference between UNDE ...
- JavaScript中的Date,RegExp,Function对象
Date对象 创建Date对象 //方法1:不指定参数var nowd1=new Date();alert(nowd1.toLocaleString( ));//方法2:参数为日期字符串var now ...
随机推荐
- openstack-ocata-环境准备1
Openstack环境准备1. 最少两台机器2. Controller:1核cpu 4G内存 5G硬盘3. Computer:1核cpu 2G内存 10G硬盘4. 至少两个网卡,本次采用四个网卡(1网 ...
- 使用static与const关键字时需要掌握的知识
static:1.不考虑类,static的作用: 1)第一个作用:隐藏.使得全局变量和函数对其它文件不可见,同时避免了不同文件的命名冲突. 2)第二个作用:默认初始化为0.未初始化的全局静 ...
- 如何修改64位Eclipse中的代码字体大小
1.双击打开Eclipse,如下图所示: 2.找到菜单栏中的Window,单击它,选择Preferences 3.在左侧的树形菜单中找到General--->Appearance--->C ...
- javascript中的内存管理和垃圾回收
前面的话 不管什么程序语言,内存生命周期基本是一致的:首先,分配需要的内存:然后,使用分配到的内存:最后,释放其内存.而对于第三个步骤,何时释放内存及释放哪些变量的内存,则需要使用垃圾回收机制.本文将 ...
- 系统架构以及需要导入的jar包
架构: Servlet +JSP +JavaBean +JDBC 需要导入的jar包: MYSQL: 数据库驱动 C3PO连接池: (这个需要配置文件) C3PO DBUtils:特点:轻量级首选,增 ...
- JavaScript小括号、中括号、大括号的多义性
语义1,函数声明时参数表 func(arg1,arg2){ // ... } 语义2,和一些语句联合使用以达到某些限定作用 // 和for in一起使用 for(var a in obj){ // . ...
- js实现内容点击复制
<!DOCTYPE html><html> <head> <script type="text/javascript"> funct ...
- Android破解学习之路(七)—— 乐秀视频编辑 内购破解 专业版 价值25元的破解
按照之前的支付宝破解,搜索9000的十六进制,之后... 但是,这样测试的时候,没有破解成功,便是继续研究 搜索关键字支付失败,之后找到了指定的smali文件,观察了许久,发现里面有个switch跳转 ...
- Entity Framework 乐观并发处理
Entity Framework 乐观并发处理 有一段时间没有更新博客了,今天终于有一些时间,和大家讨论一个Entity Framework 乐观并发处理的问题.首先需要说明的是,这里提到的 “并发” ...
- (jzoj snow的追寻)线段树维护树的直径
jzoj snow的追寻 DFS序上搞 合并暴力和,记录最长链和当前最远点,距离跑LCA # include <stdio.h> # include <stdlib.h> # ...