在算法中,条件判断是出现频率最高的基础知识之一。从语法层面来说,这是非常简单的,但是落地到具体的实践和逻辑中去,条件判断应该如何写得更准确,往往是一个非常困难的点。
单独写这篇文章的主要目的并不是说要教大家条件判断的基础语法,因为我相信这些大家都已经很熟悉了,我只是简单的过一遍基础,更关键的 是要让大家对这个知识点引起重视,并在后续的学习中,作为一个重要的知识点去做知识体系的归纳与总结。
条件判断的基本形式如下:
1if(condition) {2// do something3}
1if(condition) {2// do something3} else {4// do something else5}
其中,condition
是一个布尔表达式,当其值为 true
时,执行 do something
中的语句,否则跳过或者执行 else
中的语句。如果 condition
是一个非布尔类型的值,会先将其转换为布尔类型,然后再进行判断。
注意:在 JavaScript 中,
0
、NaN
、null
、undefined
、""
这五个值会被转换为false
,其他的值都会被转换为true
。
当执行表达式比较简单时,我们也可以用三元运算符来代替 if else
,下面两种写法是等价的:
1const age = 262let beverage3if(age >= 21) {4beverage = 'Beer'5} else {6beverage = 'Juice'7}8console.log(beverage); // Beer
1const age = 262const beverage = age >= 21 ? 'Beer' : 'Juice'3console.log(beverage); // Beer
除此之外,如果有多个条件需要判断时,我们可以使用 else if
来进行链式判断,如下所示:
1if(condition1) {2// do something3} else if(condition2) {4// do something else5} else if(condition3) {6// do something else7} else {8// do something else9}
当条件类型是一个变量对应多个可能值时,我们可以使用 switch
来代替这种多个 else if
的嵌套使用
10const expr = 'Papayas';20switch (expr) {30case 'Oranges':40console.log('Oranges are $0.59 a pound.');50break;60case 'Mangoes':70case 'Papayas':80console.log('Mangoes and papayas are $2.79 a pound.');90// Expected output: "Mangoes and papayas are $2.79 a pound."10break;11default:12console.log(`Sorry, we are out of ${expr}.`);13}
条件判断的短路特性(Short-circuit evaluation)是编程语言中逻辑运算符(如 && 和 ||)的一个重要行为特性。
1、逻辑与 (&&) 的短路特性
对于表达式 A && B:
1function canProceed(value) {2return value && validate(value); // 如果 value 为假,validate 不会被调用3}
2、逻辑或 (||) 的短路特性
对于表达式 A || B:
1function getDefault(value) {2return value || defaultValue; // 如果 value 为真,defaultValue 不会被计算3}
利用这样的短路特性,我们可以将执行频率成本更低的条件判断放到前面从而提高执行效率,避免不必要的逻辑运算。
在算法中条件判断的运用场景特别多,我们这篇文章就以边界条件为例跟大家提前分享一下,在后续的学习中,我们还会有更多的运用场景需要学习
场景:当我们在切换页面时,
先直接看一下演示案例以及代码。
10import { useRef, useState } from 'react'20import Button from '@/components/ui/button'30import Number from './number'4050export default function Demo01() {60const arr = useRef([1, 2, 3, 4, 5])70const [current, setCurrent] = useState(0)8090function __clickprev() {10let _cur = arr.current.length - 111if (current > 0) {12_cur = current - 113}14setCurrent(_cur)15}1617function __clicknext() {18let _cur = 019if (current < arr.current.length - 1) {20_cur = current + 121}2223setCurrent(_cur)24}2526return (27<div className='flex items-center justify-center space-x-2'>28<Button onClick={__clickprev}>上一页</Button>2930<div className='h-40 flex-1 bg-amber-200 text-2xl flex items-center justify-center rounded-md'>31<Number value={arr.current[current]} />32</div>33<Button onClick={__clicknext}>下一页</Button>34</div>35)36}
在实现这个场景的过程中,我们设计了一个指针,用于指向当前页面。我们会根据该指针的值来明确到底应该在页面中渲染什么内容,利用 React 的机制,当指针发生变化时,页面内容也显示对应的数字内容。
1// 定义一个数组,用于表示多个页面内容2const arr = useRef([1, 2, 3, 4, 5])3// 定义一个指针,指向当前页面4const [current, setCurrent] = useState(0)
在点击向下的切换的过程中,我们需要修改该指针的值,让指针往下移动一个位置即可,以确保页面能够及时发生变化。
1function __clicknext() {2setCurrent(current + 1)3}
但是我们还有边界条件没有处理,一共只有 5 个页面,指针不能一直往后移动,因此,在移动到数组的最后一个位置时,还要往后移动的话,则将指针重置为第一个位置 0
10function __clicknext() {20// 如果当前页还不是最后一页30if (current < arr.current.length - 1) {40// 则将指针往后移动一位50setCurrent(current + 1)60} else {70// 已经移动到最后一位,重置为第一位80setCurrent(0)90}10}
在这个思维的基础之上,我们可以换一种写法,用于简化 if else
。这个思路是声明一个中间变量,来表示当前指针的预期值。
如果满足递增的条件,则重置该预期值为正确的递增值
10function __clicknext() {20// 设置预期值30let _cur = 040// 如果还没有移动到最后一位,则重置预期值50if (current < arr.current.length - 1) {60_cur = current + 170}80// 修改指针90setCurrent(_cur)10}
大家可以花一点时间体会一下写法的转变。从内存占用的角度来说,第一种方式占用的内存更少,没有额外使用临时变量。只是有时候如果你不喜欢 else
,则可以采用这种方式优化写法