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 ...
随机推荐
- R︱mlr包帮你挑选最适合数据的机器学习模型(分类、回归)+机器学习python和R互查手册
一.R语言的mlr packages install.packages("mlr")之后就可以看到R里面有哪些机器学习算法.在哪个包里面. a<-listLearners() ...
- 利用squid 搭建简单的透明代理服务器
环境介绍 虚拟主机1: ip eth0192.168.0.100/24 eth1: 200.168.0.100/24 虚拟主机2(模拟外网) 200.168.0.109/24 (运行web serve ...
- 解决MyEclipse中的Building workspace问题
解决MyEclipse中的Building workspace问题 1.方法一 点击"Project",取消勾选"Build Automatically" 2. ...
- Java获取当前的年月
今天,我在尝试从数据库取数据的过程中,发现页面初始化时需要给时间控件赋初值.于是,我就写了一个获取当前年月的时间工具类. 1.具体源码如下: YearAndMonth.java: /** * @Tit ...
- SMBus
SMBus (System Management Bus,系统管理总线) 是1995年由Intel提出的,应用于移动PC和桌面PC系统中的低速率通讯.希望通过一条廉价并且功能强大的总线(由两条线组成) ...
- directX--关于CSource和CSourceStream (谁调用了fillbuffer)
CSourceStream类,是CSource类的OutputPin[source.h/source.cpp]派生自CAMThread和CBaseOutputPinl 成员变量: CS ...
- CF367 E - Working routine
十字链表模拟 #include<bits/stdc++.h> using namespace std; int n,m,q; struct Node{ int v; int d,r; }m ...
- C#图解教程 第九章 语句
语句 什么是语句控制流语句if语句if-else语句while循环do循环for循环 for语句中变量的作用域初始化和迭代表达式中的多表达式 switch语句 分支示例switch语句补充分支标签 跳 ...
- Codeforces Round #446 (Div. 2)
Codeforces Round #446 (Div. 2) 总体:rating涨了好多,虽然有部分是靠和一些大佬(例如redbag和ShichengXiao)交流的--希望下次能自己做出来2333 ...
- 【BZOJ1008】【HNOI2008】越狱(组合数学)
题面 题目描述 监狱有连续编号为1...N的N个房间,每个房间关押一个犯人,有M种宗教,每个犯人可能信仰其中一种.如果相邻房间的犯人的宗教相同,就可能发生越狱,求有多少种状态可能发生越狱 输入输出格式 ...