JS运算符你不知道的那些事!

818 阅读6分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

本文同时参与 「掘力星计划」,赢取创作大礼包,挑战创作激励金

是不是总能看到各种的JS优化,JS技巧,其实原理都在这些基础知识里你知道吗?🧐

提问

PS:答案都在文中

👉 1++的结果是什么?

👉1 || 0的结果是什么?

👉 你知道【短路求值】吗?

👉 说说||(或)、&&(与)、!(非)、空值合并运算符'??'的优先级

👉 上期回顾:JavaScript里的数学运算符

活动需要集齐🥂【10个评论】🥂,当前进度还是为零😭,所以

9H2{R6QV0ZF0{JUH~~P3RPM.png



自增/自减

🎨示例

let counter = 2;

counter++;   // 等同于 counter = counter + 1 

counter--;   // 等同于 counter = counter - 1 

💥注意:自增/自减只能应用于变量,如果直接用在数字会报错

image-20211015202022455



逻辑运算符

JavaScript 中有三个逻辑运算符:||(或),&&(与),!(非)。

||(或)+ 拓展

给定的条件中任意一个为true,结果为true。(只需要对1个)

console.log( true || true );   // true
console.log( false || true );  // true
console.log( true || false );  // true
console.log( false || false ); // false

📖拓展

问:1 || 0 的值是什么?

👇

👇

👇

👇

第一反应是不是想说true🤣

在JS中, ||或运算符 做了如下的事情:
🍇: 从左到右依次计算操作数。
🍈: 处理每一个操作数时,都将其转化为布尔值。如果结果是 true,就停止计算,返回这个操作数的初始值。
🍉: 如果所有的操作数都被计算过(也就是,转换结果都是 false),则返回最后一个操作数。

也就是说返回的值实际上是操作数的【初始形式】,不会做布尔转换。

📒总结: ||(或)运算的返回值是第一个为的值,或者全部值的最后一个

所以上面问题的答案是:

image-20211016142437330

🎨更多示例

console.log( null || 1 ); // 1(1 是第一个真值)
console.log( null || 0 || 1 ); // 1(第一个真值)
console.log( undefined || null || 0 ); // 0(都是假值,返回最后一个值)



与“纯粹的、传统的、仅仅处理布尔值的或运算”相比,这个规则就引起了一些很【有趣的用法】。

1、获取变量列表或者表达式中的第一个真值。

🎨示例:想选出几个变量中有值的那一个,如果都没值,则输出默认值

//如果有设置名称则输出名称,如果没有设置,则输出"Anonymous"(匿名者)
let firstName = "";
let lastName = "";
let nickName = "Axjy";

console.log( firstName || lastName || nickName || "Anonymous"); // Axjy

2、短路求值(Short-circuit evaluation)

短路求值(Short-circuit evaluation,又称最小化求值),是一种逻辑运算符的求值策略。只有当第一个运算数的值无法确定逻辑运算的结果时,才对第二个运算数进行求值。👉维基百科

比如 || (或)运算,当第一个运算数为true时,结果一定为true,在这种情况下,就不需要知道第二个运算数的具体值。

你可以利用这个特效,做一些只在左侧添加为假时才执行的命令

true || console.log("不会被执行");
false || console.log("会被执行");

可以看到,或运算的操作数,不但可以是一个值,还可以是变量赋值或者函数调用

&&(与)+ 拓展

当两个操作数都是真值时,与运算返回 true,否则返回 false

console.log( true && true );   // true
console.log( false && true );  // false
console.log( true && false );  // false
console.log( false && false ); // false

📖拓展

1、&&(与)运算可以用来寻找第一个假值

🎨

// 如果第一个操作数是假值,
// 与运算将直接返回它。第二个操作数会被忽略
console.log( null && 5 ); // null
console.log( 0 && "no matter what" ); // 0

// 如果第一个操作数是真值,
// 与运算返回第二个操作数:
console.log( 1 && 0 ); // 0
console.log( 1 && 5 ); // 5

与运算 && 做了如下的事:
🍊: 从左到右依次计算操作数。
🍋:在处理每一个操作数时,都将其转化为布尔值。如果结果是 false,就停止计算,并返回这个操作数的初始值。
🍌:如果所有的操作数都被计算过(例如都是真值),则返回最后一个操作数。

📒总结:&&(与)运算的返回值是第一个为的值,或者全部值的最后一个

2、和 || 或运算一样,&&(与)运算也可用作短路求值,当&&(与)的第一个运算数的值为false时,其结果必定为false。



!(非)

感叹符号 ! 表示布尔非运算符,表示取相反的值

result = !value;

优先级问题

与运算 && 的优先级比或运算 || 要高

a && b || c && d
等同于
(a && b) || (c && d)

非运算符 ! 的优先级在所有逻辑运算符里面最高,所以它总是在 &&|| 之前执行。

📒总结:!(非)> &&(与)> ||(或)



空值合并运算符 '??'

📖作用:它主要用来获取已定义的值,什么叫已定义?就是这个值既不是 null 也不是 undefined

a ?? b 的结果是:
- 如果 a 是已定义的,则结果为 a
- 如果 a 不是已定义的,则结果为 b

📒总结:如果第一个参数不是 null/undefined,则 ?? 返回第一个参数。否则,返回第二个参数。

📖使用场景:通常 ?? 的使用场景是,为可能是未定义的变量提供一个默认值。

🎨示例:当 user 是未定义的,则显示 Anonymous

let user;
console.log(user ?? "Anonymous"); // Anonymous

如果有认真看的话,是不是发现,其实上面说的 ||(或)运算也是一样的可以实现,那为什么还要添加空值合并运算符 ?? 呢?

它们之间重要的区别是

  • || 返回第一个 值。
  • ?? 返回第一个 已定义的 值。

|| 无法区分 false0、空字符串 ""null/undefined。它们都一样 —— 假值。如果其中任何一个是 || 的第一个参数,那么我们将得到第二个参数作为结果。

不过在实际中,我们可能只想在变量的值为 null/undefined 时使用默认值。也就是说,当该值确实未知或未被设置时。

🎨示例

let height = 0;

console.log(height || 100); // 100   先检查height是否为假,是则返回第二个参数100
console.log(height ?? 100); // 0     先检查height是否为 null/undefined,不是,则返回它的值0

很明显,当0是有效值时,它并不应该被替换成默认值,所以??的结果才是正确的。

??的优先级问题

?? 运算符的优先级相当低,所以如果你希望它生效,最好都加上括号

??&&||一起使用时,如果没加括号会直接报错;

image-20211016153806453




条件运算符 ?

在JavaScript中,需要根据不同条件执行不同的操作时有两种方式

  • 使用if语句
  • 使用条件运算符 ? (也称为“问号”运算符)

有时我们需要根据一个条件去赋值一个变量,使用“问号”运算符可以让我们更简短地达到目的

📖语法let result = condition ? value1 : value2;

(计算条件结果,如果结果为真,则返回 value1,否则返回 value2。)

这个运算符通过问号 ? 表示。有时它被称为【三元运算符】,被称为“三元”是因为该运算符中有三个操作数。

🎨示例

console.log( '0' ? '真' : '假' )  //真
console.log( 0 ? '真' : '假' )  //假

多个'?'

使用一系列问号 ? 运算符可以返回一个取决于多个条件的值。

let score = 100;

let message = (score < 60) ? '不及格!' :
  (score < 79) ? '合格!' :
  (score < 89) ? '良好!' :
  '优秀!';

console.log( message );

等同于

if (score < 60) {
  message = '不及格!';
} else if (score < 79) {
  message = '合格!';
} else if (score < 89) {
  message = '良好!';
} else {
  message = '优秀!';
}

三元运算符什么时候用合适?

虽然三元运算符更简短,但是可读性不太好,所以建议不要滥用;

  • 如果需要根据条件返回一个或另一个,可以使用三元运算符
  • 如果需要根据条件执行不同的代码分支,请使用 if

结语

文章会持续更新,优化,以及重构!

参考资料:

Basic operators, maths

Conditional branching: if, '?'

Logical operators

Nullish coalescing operator '??'



🎨【点赞】【关注】不迷路,更多前端干货等你解锁

往期推荐

👉 来看看最新版的谷歌浏览器开发者工具都更新了些什么?

👉 layui镜像合集+怎么把人家整个网站拷贝下来的

👉 从0开始学习JavaScript

👉 HTTP备忘录 | 常用状态码&请求头&响应头&Cookies及请求方法合集