这篇博文继续分享《高程四》第三章的内容,从3.5.8开始。
3.5.8 相等操作符
判断两个变量是否相等是编程中最重要的操作之一。在比较字符串、数值和布尔值是否相等时,过程都很直观。但是在比较两个对象是否相等时,情形就比较复杂了。ECMAScript提供了两组操作符。第一组是等于和不等于,它们在比较之前执行转换。第二组是全等和不全等,它们在比较之前不执行转换。(在《你不知道的JavaScript》中,把这两种分别介绍成“宽松相等”和“严格相等”。注意,虽然“===”要求类型和值都相等,看起来要求更高,实际上比对过程中没有发生类型转换,做的事情反而是更少的)
1. 等于和不等于
ECMAScript中的等于操作符用两个等于号( == )表示,如果操作数相等,则会返回 true 。不等于操作符用叹号和等于号( != )表示,如果两个操作数不相等,则会返回 true 。这两
个操作符都会先进行类型转换(通常称为强制类型转换)再确定操作数是否相等。
在转换操作数的类型时,相等和不相等操作符遵循如下规则。
如果任一操作数是布尔值,则将其转换为数值再比较是否相等。 false 转换为0, true 转换为1。
如果一个操作数是字符串,另一个操作数是数值,则尝试将字符串转换为数值,再比较是否相等。
如果一个操作数是对象,另一个操作数不是,则调用对象的valueOf() 方法取得其原始值,再根据前面的规则进行比较。
在进行比较时,这两个操作符会遵循如下规则。
null 和 undefined 相等。
null 和 undefined 不能转换为其他类型的值再进行比较。
如果有任一操作数是 NaN ,则相等操作符返回 false ,不相等操作符返回 true 。记住:即使两个操作数都是NaN ,相等操作符也返回 false ,因为按照规则, NaN不等于 NaN 。
如果两个操作数都是对象,则比较它们是不是同一个对象。如果两个操作数都指向同一个对象,则相等操作符返回true 。否则,两者不相等
特殊情况举例:
表达式 结果 null == undefined true "NaN" == NaN false 5 == NaN false NaN == NaN false NaN != NaN true false == 0 true true == 1 true true == 2 false undefined == 0 false null == 0 false "5" == 5 true
2. 全等和不全等
全等和不全等操作符与相等和不相等操作符类似,只不过它们在比较相等时不转换操作数。全等操作符由3个等于号( === )表示,只有两个操作数在不转换的前提下相等才返回 true。
不全等操作符用一个叹号和两个等于号( !== )表示,只有两个操作数在不转换的前提下不相等才返回 true。
let result1 = ("55" != 55); // false,转换后相等
let result2 = ("55" !== 55); // true,不相等,因为数据类型不同
另外,虽然 null == undefined 是 true (因为这两个值类似),但 null === undefined 是 false ,因为它们不是相同的数据类型。
注意 由于相等和不相等操作符存在类型转换问题,因此推荐使用全等和不全等操作符。这样有助于在代码中保持数据类型的完整性。(除非是if比较null和undefined的时候可以用“==”其他情况不建议)
3.5.9 条件操作符
条件操作符(也就是三目运算符)是ECMAScript中用途最为广泛的操作符之一,语法跟Java中一样。
variable = boolean_expression ? true_value : false_value;
上面的代码执行了条件赋值操作,即根据条件表达式boolean_expression 的值决定将哪个值赋给变量 variable 。如果 boolean_expression 是 true ,则赋值 true_value ;如果 boolean_expression 是 false ,则赋值false_value 。
3.5.10 赋值操作符
简单赋值用等于号( = )表示,将右手边的值赋给左手边的变量,如下所示:
let num = 10;
复合赋值使用乘性、加性或位操作符后跟等于号( = )表示。这些赋值操作符是类似如下常见赋值操作的简写形式:
let num = 10;
num = num + 10;
以上代码的第二行可以通过复合赋值来完成:
let num = 10;
num += 10;
每个数学操作符以及其他一些操作符都有对应的复合赋值操作符:
乘后赋值( *= )
除后赋值( /= )
取模后赋值( %= )
加后赋值( += )
减后赋值( -= )
左移后赋值( <<= )
右移后赋值( >>= )
无符号右移后赋值( >>>= )
这些操作符仅仅是简写语法,使用它们不会提升性能。
3.5.11 逗号操作符
逗号操作符可以用来在一条语句中执行多个操作,如下所示:
let num1 = 1, num2 = 2, num3 = 3;
在一条语句中同时声明多个变量是逗号操作符最常用的场景。
也可以使用逗号操作符来辅助赋值。在赋值时使用逗号操作符分隔值,最终会返回表达式中最后一个值:
let num = (5, 1, 4, 8, 0); // num的值为0
在这个例子中, num 将被赋值为0,因为0是表达式中最后一项。逗号操作符的这种使用场景并不多见,但这种行为的确存在。
3.6 语句
ECMA-262描述了一些语句(也称为流控制语句),而ECMAScript中的大部分语法都体现在语句中。语句通常使用一或多个关键字完成既定的任务。语句可以简单,也可以复杂。简单的如告诉函数退出,复杂的如列出一堆要重复执行的指令。
3.6.1 if 语句
if 语句是使用最频繁的语句之一,语法如下:
if (condition) statement1 else statement2
这里的条件( condition )可以是任何表达式,并且求值结果不一定是布尔值。ECMAScript会自动调用 Boolean() 函数将这个表达式的值转换为布尔值。如果条件求值为 true ,则执行语句statement1 ;如果条件求值为 false ,则执行语句statement2 。这里的语句可能是一行代码,也可能是一个代码块(即包含在一对花括号中的多行代码。如果有多条语句,就必须使用花括号)。
这里的最佳实践是使用语句块,即使只有一行代码要执行也是如此。这是因为语句块可以避免对什么条件下执行什么产生困惑。
可以像这样连续使用多个 if 语句:(如果有多个条件需要判断,中间可以用else if)
if (condition1) statement1 else if (condition2)
statement2 else statement3