JavaScript中的两个等号(==)和三个等号(===)
“Determining whether two variables are equivalent is one of the most important operations in programming.” (确定两个变量是否相等是编程中最重要的操作之一)
——Nicholas Zakas
JavaScript中作比较有两个方式:严格模式(strict comparison 使用三个等号 ===)和概要模式(abstract comparison 使用两个等号 ==),对于他们的意义和行为,本文做一个归纳。
为了避免舍本逐末,学习任何知识应该先从标准的定义开始,下面是这两种比较方式在ECMA262标准中的定义:
严格模式 ===
The Strict Equality Comparison Algorithm(严格相等比较算法)
The comparison x === y, where x and y are values, produces true or false. Such a comparison is performed as follows:(判断步骤如下,注意次序)
- If Type(x) is different from Type(y), return false.
- If Type(x) is Undefined, return true.
- If Type(x) is Null, return true.
- If Type(x) is Number, then
- If x is NaN, return false.
- If y is NaN, return false.
- If x is the same Number value as y, return true.
- If x is +0 and y is −0, return true.
- If x is −0 and y is +0, return true.
- Return false.
- If Type(x) is String, then return true if x and y are exactly the same sequence of characters (same length and same characters in corresponding positions); otherwise, return false.
- If Type(x) is Boolean, return true if x and y are both true or both false; otherwise, return false.
- Return true if x and y refer to the same object. Otherwise, return false.
概要模式 ==
The Abstract Relational Comparison Algorithm
The comparison x < y, where x and y are values, produces true, false, or undefined (which indicates that at least one operand is NaN). In addition to x and y the algorithm takes a Boolean flag named LeftFirst as a parameter. The flag is used to control the order in which operations with potentially visible side-effects are performed upon x and y. It is necessary because ECMAScript specifies left to right evaluation of expressions. The default value of LeftFirst is true and indicates that the x parameter corresponds to an expression that occurs to the left of the y parameter’s corresponding expression. If LeftFirst is false, the reverse is the case and operations must be performed upon y before x. Such a comparison is performed as follows:(判断步骤如下,注意次序)
- If the LeftFirst flag is true, then
- Let px be the result of calling ToPrimitive(x, hint Number).
- Let py be the result of calling ToPrimitive(y, hint Number).
- Else the order of evaluation needs to be reversed to preserve left to right evaluation
- Let py be the result of calling ToPrimitive(y, hint Number).
- Let px be the result of calling ToPrimitive(x, hint Number).
- If it is not the case that both Type(px) is String and Type(py) is String, then
- Let nx be the result of calling ToNumber(px). Because px and py are primitive values evaluation order is not important.
- Let ny be the result of calling ToNumber(py).
- If nx is NaN, return undefined.
- If ny is NaN, return undefined.
- If nx and ny are the same Number value, return false.
- If nx is +0 and ny is −0, return false.
- If nx is −0 and ny is +0, return false.
- If nx is +∞, return false.
- If ny is +∞, return true.
- If ny is −∞, return false.
- If nx is −∞, return true.
- If the mathematical value of nx is less than the mathematical value of ny —note that these mathematical values are both finite and not both zero—return true. Otherwise, return false.
- Else, both px and py are Strings
- If py is a prefix of px, return false. (A String value p is a prefix of String value q if q can be the result of concatenating p and some other String r. Note that any String is a prefix of itself, because r may be the empty String.)
- If px is a prefix of py, return true.
- Let k be the smallest nonnegative integer such that the character at position k within px is different from the character at position k within py. (There must be such a k, for neither String is a prefix of the other.)
- Let m be the integer that is the code unit value for the character at position k within px.
- Let n be the integer that is the code unit value for the character at position k within py.
- If m < n, return true. Otherwise, return false.
通过定义,可以归纳出下面的特点:
- === 不做类型转换,类型不同的一定不等,返回false;
- 两个string严格相等表示它们有相同的字符排列、相同的长度和每个位置的字符都相同;
- 两个number严格相等表示它们有相同的数值,NaN和任何东西都不相等,包括NaN它自己;正负零彼此之间相等;
- 两个boolean严格相等表示它们同时为true或者同时为false;
- 两个不同的object在严格和概要比较中都不相等,返回false;
- 两个object相等唯一的情况是他们引用了相同的object;
- == 在两边值类型不同的时候,会做如下的转换再严格比较:
- null == undefined 但是 null !== undefined;
- 如果有一个操作数是一个数字或布尔值,如果可能,另一个操作数转换为数字;否则,如果其中一个操作数为字符串,如果可能,另一个操作数被转换为字符串;
- 如果两个操作数都是对象,那会比较对象在内存中的引用是否相同。
根据上面的规则,我们知道:如果在比较时两个变量的类型很重要,就要使用严格比较(===);否则可以使用一般比较(==)。
在JavaScript中,下面的值被当做假(false),除了下面列出的值,都被当做真(true):
- false
- null
- undefined
- 空字符串 ”
- 数字 0
- NaN
分析如下的代码:
1
2
3
4
5
6
7
8
9
10
11
12
|
5=='5' // true 右边的字符串会被转换为数字,然后进行比较
"1"==true // true true会先转换成数值 1,然后进行比较
//注意 String 对象和 string字符串不同,String对象一般来说很少使用
vara=newString("foo");
varb=newString("foo");
a==b //false
a===b //false
a=="foo" //true
a==="foo"//false
|
注意在使用 == 时,在类型不同时,会进行强制类型转换,这个转换的规则十分复杂(上面的特点中有简单的说明,详见 ToPrimitive),不了解规则时,会发现表现十分的奇怪:
1
2
3
4
5
6
7
8
9
10
11
|
''=='0' //false
0=='' //true
0=='0' //true
false=='false' //false
false=='0' //true
false==undefined //false
false==null //false
null==undefined //true
' \t\r\n '==0 //true
|
通过上面的例子可以看出,== 在传递性(即 a == b, a == c 推出 b == c)上是不可靠的,以上例子中如果使用 ===,结果都会是 false。所以建议除非非常清楚自己想要的,一般尽量使用 === 来进行比较。
下面介绍与判断相等相关的几个知识:
!! 运算符
注意下面的代码:
1
2
|
NaN === NaN //false
!!NaN===!!NaN //true
|
我们经常会在代码中看到 !! 运算符,它是一个编程技巧,作用主要是把一个变量或表达式转换为boolean,看下面的代码(均返回 true):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
!!false===false
!!true===true
!!0===false
!!parseInt("foo")===false// NaN 为 false
!!1===true
!!-1===true
!!""===false//空字符串为false
!!"foo"===true //非空字符串都为true
!!"false"===true //非空字符串都为true
!!window.foo===false//undefined为false
!!null===false//null为false
!!{}===true //空对象为true
!![]===true //空数组为true
!!newBoolean(false)===true //这里是个对象
!!Boolean(false)===false //这里才是boolean值
|
相类似的快速转换类型写法还有下面的两个:
Number(foo) === +foo
String(foo) === ”+foo
变量和常量的顺序
大家在阅读js资料时可能会发现有这样的写法推荐,即变量放在双等号的右边,常量放在左边:
1
2
3
4
5
|
//尽量使用
if('0'==a){......
//不要使用
if(a=='0'){......
|
这是“Yoda表示法”,名字来源于《星球大战》的 Yoda 大师。他说话的单词顺序相当奇特,比如:“Backwards it is, yes!”。
这样写主要是防止缺少等号的笔误,比如把 if ( a == ’0′ ) 误写成了 if ( a = ’0′ ),如果采用了常量在前的判断写法,如果把 if ( ’0′ == a ) 误写成了 if ( ’0′ = a ),则会抛出错误(ReferenceError: Invalid left-hand side in assignment)。
一般来说,作为代码书写规范来说,推荐常量在左进行判断的写法。
转载于:https://www.cnblogs.com/littleCode/p/3709056.html
JavaScript中的两个等号(==)和三个等号(===)相关推荐
- JS/JavaScript中两个等号 == 和 三个等号 === 的区别
JavaScript中两个等号 == 和 三个等号 === 的区别 一.概念 == 和 === (1) "=="叫做相等运算符,"==="叫做严格运算符. ...
- js两个等号和三个等号_js中两个等号(==)和三个等号(===)的区别
js中两个等号(==)和三个等号(===)的区别: 1. "=="表示:equality -> 等同 的意思,"=="使用两个等号时,如果两边值的类型不同 ...
- js中两个等号“==“与三个等号“===“有何不同
一.1个等号"=": 首先一个等号"=",大家都知道,一般在编程语言中是用来做赋值操作的,也叫赋值运算符,即把等号右边的值,赋值给左边声明的变量. 例如:在js ...
- java两字符串是否相等_Java与JavaScript中判断两字符串是否相等的区别
JavaScript是一种常用的脚本语言,这也决定了其相对于其他编程语言显得并不是很规范.在JavaScript中判断两字符串是否相等 直接用==,这与C++里的String类一样.而Java里的等号 ...
- 两个等号(==)和三个等号(===)的区别
2019独角兽企业重金招聘Python工程师标准>>> 两个等号(==)和三个等号(===)的区别: 1. "=="表示:equality -> 等同 的意 ...
- 网页html怎么调整字样,怎么在css中设置两个字和三个字对齐
怎么在css中设置两个字和三个字对齐 发布时间:2021-03-09 15:16:12 来源:亿速云 阅读:85 作者:Leah 怎么在css中设置两个字和三个字对齐?针对这个问题,这篇文章详细介绍了 ...
- 如何在 JavaScript 中比较两个日期?
平等比较 在大多数情况下,不建议使用松散或严格的相等运算符 ( ==or )在 JavaScript 中比较两个日期.===等式运算符比较Date对象引用,false即使日期值相同,也会产生 : co ...
- js中两个等号和三个等号区别?
== equality 等同,=== identity 恒等.==, 两边值类型不同的时候,要先进行类型转换,再比较. ==,不做类型转换,类型不同的一定不等.下面分别说明: 先说 ===,这个比较简 ...
- Js中两个等号(==)和三个等号(===)的区别
1. "=="表示:equality ->等同的意思,"=="使用两个等号时,如果两边值的类型不同的时候,是要先进行类型转换后,才能做比较 2. &quo ...
最新文章
- java定时任务框架elasticjob详解
- matlab柱状斜线_Matlab小练习:按斜线方向依次赋值矩阵
- 解析JVM内存区域组成
- STM32工作笔记0059---独立看门狗实验
- python appium api pc_Appium Python API 中文版
- 寫程式不需要天份,也不需要熱情
- 排序(python)
- listview复用机制研究
- 2021.9.11周六PAT甲级考试复盘与总结
- HTML页面跳转的方法
- 什么是JavaSE,写给第一次接触Java的人
- 串口数据接收、发送与USB转串口驱动下载
- Pandas 筛选数据的 8 个神操作
- 重读《从菜鸟到测试架构师》-- 开发团队做的远不仅是开发
- 关于1NF、2NF、3NF、BCNF的常考判定
- SSM框架学习——Maven进阶学习
- 一元多项式因式分解的唯一性定理
- git-cz 规范提交代码注释
- 北京35岁程序员失业,感叹:编程估计没戏了,想去卖点煎饼果子养家~
- 工作流初始错误 泛微提交流程提示_泛微OA用户操作手册.pdf
热门文章
- VisualStudio安装
- jquery-file-upload限制文件上传大小和文件个数
- 怎样在ppt中加入随机抽号_潮流女生怎样穿更时髦?经典中加入个性,减龄时尚还高级,快入坑...
- java的隐藏函数_java – 隐藏子级数据成员的父成员函数
- 测试化验加工费云服务器文献信息,监管▕ 科研经费使用中的 “红线”和“禁区”典型问题自查清单...
- 小波变换原理_基于电压行波原理故障测距的相关问题
- python矩阵赋值提高速度_Numpy大规模矩阵运算优化加速技巧
- 怎么查到运行的时间_“我的成考录取通知书怎么还没来,它是不是迷路了?”...
- linux的常用的软件,Linux常用的软件和命令
- linux-headers,如何升级linux-headers-generic?