由undefined == null想到的

首先在这之前,我并不知道undefined == nullundefined !== null,如果你也不知道,那么可以继续阅读试着了解,如果已经知道就忽略此文吧

本文所述内容:

  1. undefinednull的区别
  2. javascript数据类型转换
  3. =====的区别(使用==时发生了什么)

1. undefinednull的区别

我首先看了这篇文章:理解Javascript_02_理解undefined和null
个人总结:虽然觉得这篇文章的有些理解是错的,但是给我很好的开了个头。他的表述是:

  • Undefined代表没有赋值的基本数据类型
  • Null代表没有赋值的引用数据类型

我们都知道,基本数据类型数据存在栈里,引用数据类型数据存在堆里,栈比堆运算速度快,堆比栈存的多。这篇文章认为,为了的这个计算效率原因,再加上“undefined 实际上是从值 null 派生来的”,基本数据类型是对应引用数据类型的子类,只不过是为了提高效率,将其放在栈内存中而已。这是错误的理解。

基本数据类型也就是原始数据类型(primitive),引用数据类型就是复合数据类型(complex),“undefined 实际上是从值 null 派生来的”个人觉得这句话只是说的字面上的派生,之所以这么理解undefined和null,是因为“历史原因”,看了下百科关于JavaScript的发明人——Brendan Eich,里面有说他的设计思路:

Paste_Image.png

javascript为什么要用2个表达方式来表述空这个概念?摘一段引用:

1.null 和 undefined在现代JS语义里面是有明确区别的:

  • null 表示一个值被定义了,定义为“空值”;
  • undefined 表示根本不存在定义。
    所以设置一个值为 null 是合理的

2.JS 中同时存在 undefined 和 null 是合理的
首先在 Java 中不存在 undefined 是很合理的:Java 是一个静态类型语言,对于 Java 来说不可能存在一个“不存在”的成员(不存在的话直接就编译失败了),所以只用 null 来表示语义上的空值。而 JavaScript 是一门动态类型语言,成员除了表示存在的空值外,还有可能根本就不存在(因为存不存在只在运行期才知道),所以这就要一个值来表示对某成员的 getter 是取不到值的。

java中null只是存粹的表示空,且不是一种任何数据类型,作为动态类型的js来说,有些值只有在运算时才能知道存不存在,必须要有一个类型来表示,所以就出现了undefined。另外js里的:typeof null === "object"应该是一个设计失误。

此处参考undefined与null的区别@ RedNax评论

最后undefined == null,就是规范定义的结果,规范第2条中说If x is null and y is undefined, return true.
此处规范中文版,所以说undefined == null并没有什么可讨论的,规范就是这么定义的,至于undefined !== null因为这就是2个不同类型的数据,肯定不相等。


2.javascript数据类型转换

讨论类似undefined == null[] !== []有何实际意义?其实,我们讨论这些问题一定要去了解其中涉及的原理,讨论单个点确实无意义。就像第一个问题:涉及的点就有类型转换和数据类型和内存管理。

此点参考数据类型转换JS 数据类型转换

我们这里讨论数据类型转换内容:

  • parseInt()和parseFloat()
  • 强制转换
  • 隐式转换

parseInt()和parseFloat()

内容 parseInt parseFloat
基数 默认十进制,八进制,十六进制可选 只能是十进制
共同点 都是将有效字符前的字符转化为数字 都只有对String类型调用这些方法,其他类型或者该字符串不是一个有效的字符串都是返回NaN

强制转换

强制转换主要指使用Number、String和Boolean三个构造函数,手动将各种类型的值,转换成数字、字符串或者布尔值。

此处查看数据类型转换即可

里面未涉及的点:valueOf()toString(),每个对象都有自己的valueOf()toString(),并且做类型转换时自动调用。

1.Object.prototype.valueOf() Object.prototype.toString()
默认情况下,对象的valueOf方法返回对象本身
toString方法返回returns "[object type]",这里的type为object

Every object has a toString() method that is automatically called when the object is to be represented as a text value or when an object is referred to in a manner in which a string is expected.

2.Array.prototype.valueOf() Array.prototype.toString()
同样,数组的valueOf方法返回的也是它本身

let arr = [1, 3, 4]
arr.valueOf() // [1, 3, 4]

toString返回的是A string representing the elements of the array.

let arr = [1, 2]
arr.toString() // 1,2

3.Function.prototype.valueOf() Function.prototype.toString()
函数的valueOf方法返回的也是它本身
这里的toString返回A string representing the source code of the function.

数据类型转换一文可知:

做Number强制转换并且参数是对象时,转换经历了3个步骤:
如果valueOf返回的是基本数据类型,则直接用基本数据类型的转换规则;如果返回的是对象,则再调用toString,得到string基本数据类型后,再转换。
对于一般的3中引用类型的数据,valueOf都会返回其本身,除非重写valueOf方法。简单来说,Number做强制转换时,直接用toString方法后再做转换就好了。

同理,String做强制转换时,是先调用的toString,如果返回的不是基本数据类型,则再调用valueOf。所以说,一般情况下valueOf都是返回的本身,没啥用,除非重写valueOf,做实事的都是toString

对于Boolean,所有对象都返回true。

总结:我们了解Boolean([]),String([])有何实际意义?真正用到的场景我想就是隐式转换了吧


3.== 与 ===的区别(隐式转换)

我们都知道,在做==比较时,不同类型的数据会先转换成一致后再做比较:

'3' == 3 // true
0 == false // true

在做===时,如果类型不一致就直接返回false了,一致的才会继续比较

其实,隐式转换包含很多场景,除了上面的==外,还有

1 + '3'  // '13'
let a = 2 > '1' ? 'string' : false
'4' - '2'
+new Date
+ {a: 1}  // NaN

隐式转换,基本类型之间到底是谁转谁呢?
就拿==来说,有以下几种情况n1 == n2

  • 如果有一个操作数为boolean值,则先转为数值后再做比较;
  • 如果n1是字符串,n2是数值,也是转换为数值再比较;
  • 如果有一个是对象,一个不是,则先调用Number做强制转换,得到基本数据类型后再比较;

也就是说,如果n1,n2类型不一致(出现boolean或数值),会优先转为数值后再进行比较。

false == 1 // false 转为0再比较
false == '2' // false转为0,'2'转为1
'3' == 2 // '3'转为3再比较

其他除了==情况下,都是根据实际情况来定,比如:

  • 在if或者三目运算符中,那肯定是转为boolean了,除了以下六个值为false,其他都是自动转为true
undefined
null
-0
0或+0
NaN
''(空字符串)

详细参考数据类型转换.

关于==时的隐式类型转换规则时,聊一聊 JS 中的『隐式类型转换』跟我的想法一致:

BABD2F96-69F1-40B9-AD50-7EE66A179887.png

总结

了解了这么多,无非就是为了知道语言自身的规则,好让我们能更好的规避错误。
当然里面涉及的点,还是很有必要了解与熟知的:js数据类型强制转换js历史
说到隐式转换,建议在所有使用条件判断的时候都使用全等运算符 === 来进行条件判断,全等运算符会先进行数据类型判断,并且不会发生隐式类型转换。

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

推荐阅读更多精彩内容