小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
本文同时参与 「掘力星计划」,赢取创作大礼包,挑战创作激励金
是不是总能看到各种的JS优化,JS技巧,其实原理都在这些基础知识里你知道吗?🧐
提问
PS:答案都在文中
👉 1++的结果是什么?
👉1 || 0的结果是什么?
👉 你知道【短路求值】吗?
👉 说说||(或)、&&(与)、!(非)、空值合并运算符'??'的优先级?
👉 上期回顾:JavaScript里的数学运算符
活动需要集齐🥂【10个评论】🥂,当前进度还是为零😭,所以
自增/自减
🎨示例:
let counter = 2;
counter++; // 等同于 counter = counter + 1
counter--; // 等同于 counter = counter - 1
💥注意:自增/自减只能应用于变量,如果直接用在数字上会报错
逻辑运算符
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
),则返回最后一个操作数。
也就是说返回的值实际上是操作数的【初始形式】,不会做布尔转换。
📒总结: ||(或)运算的返回值是第一个为真的值,或者全部假值的最后一个
所以上面问题的答案是:
🎨更多示例:
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
如果有认真看的话,是不是发现,其实上面说的 ||(或)运算也是一样的可以实现,那为什么还要添加空值合并运算符 ??
呢?
它们之间重要的区别是:
||
返回第一个 真 值。??
返回第一个 已定义的 值。
||
无法区分false
、0
、空字符串""
和null/undefined
。它们都一样 —— 假值。如果其中任何一个是||
的第一个参数,那么我们将得到第二个参数作为结果。不过在实际中,我们可能只想在变量的值为
null/undefined
时使用默认值。也就是说,当该值确实未知或未被设置时。
🎨示例:
let height = 0;
console.log(height || 100); // 100 先检查height是否为假,是则返回第二个参数100
console.log(height ?? 100); // 0 先检查height是否为 null/undefined,不是,则返回它的值0
很明显,当0是有效值时,它并不应该被替换成默认值,所以??
的结果才是正确的。
??的优先级问题
??
运算符的优先级相当低,所以如果你希望它生效,最好都加上括号;
??
和&&
或||
一起使用时,如果没加括号会直接报错;
条件运算符 ?
在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
。
结语
文章会持续更新,优化,以及重构!
参考资料:
Conditional branching: if, '?'
Nullish coalescing operator '??'
🎨【点赞】【关注】不迷路,更多前端干货等你解锁
往期推荐