声明:本文是摘自一篇文章,放在这只为做为一个笔记能更好学习。 大家知道,==是JavaScript中比较复杂的一个运算符。它的运算规则奇怪,容易让人犯错,从而成为JavaScript中“最糟糕的特性”之一。 在仔细阅读了ECMASc ...
声明:本文是摘自一篇文章,放在这只为做为一个笔记能更好学习。
大家知道,==是JavaScript中比较复杂的一个运算符。它的运算规则奇怪,容易让人犯错,从而成为JavaScript中“最糟糕的特性”之一。
在仔细阅读了ECMAScript规范的基础上,画了一张图,通过它你会彻底地搞清楚关于==的一切。同时,试图通过此文向大家证明==并不是那么糟糕的东西,它很容易掌握,甚至看起来很合理。
先上图:
图1 ==运算规则的图形化表示
==运算规则的精确描述在此:The Abstract Equality Comparison Algorithm(http://es5.github.io/#x11.9.3)。但是,这么复杂的描述,你确定看完后脑子不晕?确定立马就能拿它指导实践?
肯定不行,规范毕竟是给JavaScript运行环境的开发人员看的(比如V8引擎的开发人员们),而不是给语言的使用者看的。而上图正是将规范中复杂的描述翻译成了更容易看懂的形式。
在详细介绍图1中的每个部分前,我们来复习一下JS中关于类型的知识:
JS中的值有两种类型:原始类型(Primitive)、对象类型(Object)。
原始类型包括:Undefined、Null、Boolean、Number和String等五种。
Undefined类型和Null类型的都只有一个值,即undefined和null;Boolean类型有两个值:true和false;Number类型的值有很多很多;String类型的值理论上有无数个。
所有对象都有valueOf()和toString()方法,它们继承自Object,当然也可能被子类重写。
现在考虑表达式:
x == y
其中x和y是上述六种类型中某一种类型的值。
当x和y的类型相同时,x == y可以转化为x === y,而后者是很简单的(唯一需要注意的可能是NaN),所以下面我们只考虑x和y的类型不同的情况。
1 有和无
在图1中,JavaScript值的六种类型用蓝底色的矩形表示。它们首先被分成了两组:
分组的依据是什么?我们来看一下,右侧的Undefined和Null是用来表示不确定、无或者空的,而右侧的四种类型都是确定的、有和非空。我们可以这样说:
左侧是一个存在的世界,右侧是一个空的世界。
所以,左右两个世界中的任意值做==比较的结果都是false是很合理的。(见图1中连接两个矩形的水平线上标的false)
2 空和空
JavaScript中的undefined和null是另一个经常让我们崩溃的地方。通常它被认为是一个设计缺陷,这一点我们不去深究。不过我曾听说,JavaScript的作者最初是这样想的:
假如你打算把一个变量赋予对象类型的值,但是现在还没有赋值,那么你可以用null表示此时的状态(证据之一就是typeof null 的结果是'object');相反,假如你打算把一个变量赋予原始类型的值,但是现在还没有赋值,那么你可以用undefined表示此时的状态。
不管这个传闻是否可信,它们两者做==比较的结果是true是很合理的。(见图1中右侧垂直线上标的true)
在进行下一步之前,我们先来说一下图1中的两个符号:大写字母N和P。这两个符号并不是PN结中正和负的意思。而是:
ToPrimitive(obj)等价于:先计算obj.valueOf(),如果结果为原始值,则返回此结果;否则,计算obj.toString(),如果结果是原始值,则返回此结果;否则,抛出异常。
注:此处有个例外,即Date类型的对象,它会先调用toString()方法,后调用valueOf()方法。
在图1中,标有N或P的线表示:当它连接的两种类型的数据做==运算时,标有N或P的那一边的操作数要先执行ToNumber或ToPrimitive变换。
3 真与假
从图1可以看出,当布尔值与其他类型的值作比较时,布尔值会转化为数字,具体来说
true ->
原标题:对于JS == 运算的一些理解
关键词:JS
*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们:
admin#shaoqun.com
(#换成@)。