JS的逻辑运算符与赋值以及?和??

136 阅读6分钟

JS的逻辑运算符与赋值以及?和??

逻辑运算符

JS中有三种逻辑运算符:&&(逻辑与),||(逻辑或)和!(逻辑非)。这些运算符可以用来组合或取反布尔值,也可以用来进行短路求值(short-circuit evaluation)。

短路求值是指,当逻辑运算符的第一个操作数已经能够确定整个表达式的值时,就不再计算第二个操作数,而直接返回第一个操作数的值。例如,true || anything的值总是true,所以anything不会被求值。同理,false && anything的值总是false,所以anything也不会被求值。

逻辑运算符的优先级是:! > && > ||。如果要改变运算顺序,可以使用括号。

下面是一些例子:

  • "" | "s":这里的|不是逻辑运算符,而是按位或(bitwise OR)运算符,它会将两个操作数转换为32位整数,然后对每一位进行或运算,最后返回一个整数。空字符串""转换为整数是0,字符串"s"转换为整数是NaNNaN按位或任何数都是0,所以这个表达式的值是0
  • "" || "s":这里的||是逻辑或运算符,它会将两个操作数转换为布尔值,然后进行或运算,最后返回一个操作数的值。空字符串""转换为布尔值是false,字符串"s"转换为布尔值是truefalse || true的值是true,所以这个表达式的值是"s",因为它是第一个能够使整个表达式为真的操作数。
  • "" & "s":这里的&不是逻辑运算符,而是按位与(bitwise AND)运算符,它会将两个操作数转换为32位整数,然后对每一位进行与运算,最后返回一个整数。空字符串""转换为整数是0,字符串"s"转换为整数是NaNNaN按位与任何数都是0,所以这个表达式的值是0
  • 1 & 0:这里的&也是按位与运算符,它会将两个操作数转换为32位整数,然后对每一位进行与运算,最后返回一个整数。整数1的二进制表示是00000000000000000000000000000001,整数0的二进制表示是00000000000000000000000000000000,对每一位进行与运算得到00000000000000000000000000000000,转换为十进制是0,所以这个表达式的值是0
  • 0 & 0:这里的&也是按位与运算符,它会将两个操作数转换为32位整数,然后对每一位进行与运算,最后返回一个整数。整数0的二进制表示是00000000000000000000000000000000,对每一位进行与运算得到00000000000000000000000000000000,转换为十进制是0,所以这个表达式的值是0
  • 0 && 0:这里的&&是逻辑与运算符,它会将两个操作数转换为布尔值,然后进行与运算,最后返回一个操作数的值。整数0转换为布尔值是falsefalse && false的值是false,所以这个表达式的值是0,因为它是第一个能够使整个表达式为假的操作数。

?和??

JS中有两种特殊的运算符:?(可选链)和??(空值合并)。这些运算符可以用来处理一些常见的空值(nullish)情况,例如对象属性的访问或默认值的设置。

空值是指nullundefined,它们表示没有值或缺少值。空值不等于false0""NaN,它们只是表示不同的情况。

可选链运算符?可以用来访问一个对象的属性,如果对象是空值,那么就不会抛出错误,而是返回undefined。例如,a?.value表示如果a是空值,那么返回undefined,否则返回a.value。这样可以避免写很多判断语句,例如a && a.value

空值合并运算符??可以用来设置一个默认值,如果一个值是空值,那么就返回另一个值,否则返回原来的值。例如,"" ?? "s"表示如果""是空值,那么返回"s",否则返回""。这样可以避免使用逻辑或运算符||来设置默认值,因为||会将所有假值(falsy)都视为空值,例如0""NaN

可选链运算符和空值合并运算符的优先级是:? > ??。如果要改变运算顺序,可以使用括号。

下面是一些例子:

  • a?.value:这里的?是可选链运算符,它会检查a是否是空值,如果是,那么返回undefined,否则返回a.value。如果a是一个对象,那么这个表达式的值就是对象的value属性的值,如果anullundefined,那么这个表达式的值就是undefined
  • "" ?? "s":这里的??是空值合并运算符,它会检查""是否是空值,如果是,那么返回"s",否则返回""。空字符串""不是空值,所以这个表达式的值是""
  • undefined ?? "ss":这里的??也是空值合并运算符,它会检查undefined是否是空值,如果是,那么返回"ss",否则返回undefinedundefined是空值,所以这个表达式的值是"ss"
  • 0 || "s":这里的||是逻辑或运算符,它会将两个操作数转换为布尔值,然后进行或运算,最后返回一个操作数的值。整数0转换为布尔值是false,字符串"s"转换为布尔值是truefalse || true的值是true,所以这个表达式的值是"s",因为它是第一个能够使整个表达式为真的操作数。
  • 0 ?? "s":这里的??是空值合并运算符,它会检查0是否是空值,如果是,那么返回"s",否则返回0。整数0不是空值,所以这个表达式的值是0

总结

  • 按位或(|)和按位与(&)运算符会将操作数转换为32位整数,然后对每一位进行或或与运算,最后返回一个整数。
  • 逻辑或(||)和逻辑与(&&)运算符会将操作数转换为布尔值,然后进行或或与运算,最后返回一个操作数的值。这些运算符还有短路求值的特性,即当第一个操作数已经能够确定整个表达式的值时,就不再计算第二个操作数,而直接返回第一个操作数的值。
  • 可选链(?)运算符可以用来访问一个对象的属性,如果对象是空值(nullundefined),那么就不会抛出错误,而是返回undefined
  • 空值合并(??)运算符可以用来设置一个默认值,如果一个值是空值,那么就返回另一个值,否则返回原来的值。

这些运算符的优先级是:! > && > || > ? > ??。如果要改变运算顺序,可以使用括号。