JavaScript之選擇控制語句(if,switch,while,do-while,for循環)及很重要的表達式真與假
前言
您將在本文當中學習到
- 順序語句
- 分支語句
- If判斷,switch,while循壞,do..while循環,for循環,表達式中的真(true)與假(false)
在程序代碼中,我們經常都會使用流程控制語句,它是用來控制程序中各語句執行順序的語句,利用語句的組合便能完成一定功能的小邏輯模塊
流程控制方式採用結構化程序設計中規定的三種基本流程結構,即:順序結構、分支結構和循環結構,如下圖所示:
順序語句
按照正常的語句順序從上往下執行
分支語句
根據某些條件選擇執行
- if語句(針對條件單一的情況使用)
- if-else語句(針對兩種情況的時候使用)
- if-else-if語句(多重if嵌套)
- while語句(往往一進入,就需要判斷,需要條件爲真時執行一組語句)
- switch語句(多個case子句匹配)
If判斷語句
條件語句是一種代碼結構,用來測試表達式的真假,並根據布爾表達式的結果執行不同的代碼,也就是判斷結構讓程序可以選擇執行哪些程序語句
寫法
if(條件表達式) {
語句體;
}
複製代碼
注意要點:
- 條件表達式的結果必須是boolean類型
- 語句體中可以有一條語句,也可以有多條語句,如果語句體中只有一條語句,那麼{}可以省略不寫
- 可以使用三目運算符替代
應用場景
針對條件單一的情況使用單if語句 建議判斷區間或範圍的時候用
編程題
求最大值:編寫一個方法,找出兩個數字a和b中最大的那一個
示例:
輸入:a = 1, b = 2
輸出:2
複製代碼
方式1:if...else.
var maximum = function(a, b) {
if(a-b>0) {
return a;
}else {
return b;
}
// 或者如下所示:三目運算符
return a-b>0?a:b;
}
maximum(1,2)
複製代碼
方式2:使用Math提供的數據函數max
var maximum = function(a, b) {
return Math.max(a,b)
}
maximum(1,2)
複製代碼
在實際的程序代碼中:if的使用可以說無處不在
例如:上面例子中的:當表單輸入框內不爲空時,右側的按鈕激活,否則就禁用
// reducer代碼中的代碼
if(newState.inputVal !="") {
newState.btnDisable = false;
}
// UI組件中
<button onClick = { hanldeAddContent } disabled = { btnDisable }>提交</button>
複製代碼
相比於if..else
語句,switch
語句可能會沒那麼熟練,switch語句只支持常量值相等的分支判斷,而if語句支持更爲靈活,任意布爾表達式均可 但通常比一系列嵌套if語句效率更高;邏輯也更加清晰
switch語句
將表達式的值與case子句匹配,並執行與該情況相關聯的語句
應用場景:常用於等值判斷
寫法:
switch (express表達式) {
case value1:
// 當 express 的結果與 value1 匹配時,執行此處語句
語句體1;
break;
case value2:
// 當 express 的結果與 value2 匹配時,執行此處語句
語句體2;
break;
...
case valueN:
// 當 express 的結果與 valueN 匹配時,執行此處語句
語句體3;
break;
default:
// 如果 express 與上面的 value 值都不匹配,執行此處語句
語句體4;
break;
}
複製代碼
注意事項:
- 在JS中switch語句與其他變成語言的一個主要區別是:switch語句中的判斷表達式可以是任意類型,而其他語言,類如java等一些語言就要求該表達式必須爲整型
- 表達式可以是變量也可以是常量,也可以是一個複雜表達式,用全等===符號,express是一個用來與 case 子語句匹配的表達式
- case子句必須是常量表達式,case子句可以有多個,但是每一個case子句的取值不能夠重複
- default子句類似於if語句中的else語句,可以省略,但是不建議,一般用來處理一種其他的情況,可以出現在switch語句中的任意位置,但是一般建議寫在最後面
- break子句表示退出switch語句體,break語句也可以省略,一旦省略會出現break穿透現象,一般不會省略break子句
實例: 打10086時,電話呼叫案例,業務查詢請按1,手機充值請按2,業務辦理請按3,密碼服務與停復機請按4,集團業務請按8,人工服務請按0
例如如下所示:Redux中Redux中if改寫成switch語句
if語句是這樣的
import * as constants from "./actionTypes";
function reducer(state = defaultStatus, action) {
if(action.type === constants.HANDLE_INPUT_CHANGE) {
const newState = JSON.parse(JSON.stringify(state));
if(newState.inputVal !="") {
newState.btnDisable = false;
}
newState.inputVal = action.value;
return newState;
}
if(action.type === constants.HANDLE_ADD_CONTENT) {
const newState = JSON.parse(JSON.stringify(state));
newState.list.push(state.inputVal);
newState.inputVal = "";
newState.btnDisable = true;
return newState;
}
if(action.type === constants.HANDLE_DELETE_ITEM) {
const newState = JSON.parse(JSON.stringify(state));
newState.list.splice(action.index, 1);
return newState;
}
return state;
}
複製代碼
經過switch的改寫後,如下所示
import * as constants from "./actionTypes";
function reducer(state = defaultStatus, action) {
const newState = JSON.parse(JSON.stringify(state));
switch(action.type) {
case constants.HANDLE_INPUT_CHANGE:
if(newState.inputVal !="") {
newState.btnDisable = false;
}
newState.inputVal = action.value;
return newState;
case constants.HANDLE_ADD_CONTENT:
newState.list.push(state.inputVal);
newState.inputVal = "";
newState.btnDisable = true;
return newState;
case constants.HANDLE_DELETE_ITEM:
newState.list.splice(action.index, 1);
return newState;
default:
return state;
}
}
複製代碼
通過與if語句的比較:可以看的出,switch語句有幾下特點
- switch語句常用於判斷固定值的時候用
- 凡是能用switch能做的,用if都能做,單反過來則不行
- 在實際開發中,如果需要進行代碼的優化,當遇到多個條件是等值條件的判斷選擇時,不妨用switch語句替代
小結:選擇控制語句的使用
- if語句: 針對一種情況的時候
- if-else語句: 針對兩種情況的時候,非黑即白
- 多重if語句: 針對多種情況的時候,常用於區間判斷
- 嵌套if語句: 針對多種條件的時候(若是等值判斷可用switch替代)
- swtich語句: 針對條件是等值,某個固定值的情況 上面說完了選擇結構,下面來說說循環結構
while循環
可以在某個條件表達式爲真的前提下,循環執行指定的一段代碼,直到表達式不爲真時結束循環
應用場景:如果你希望在一開始條件爲真時執行一組語句,當你不知道循環執行的次數,只知道達到某個條件的時候循環繼續,那麼就選擇while循環
寫法
while (條件表達式)
statement
複製代碼
條件表達式:
在每次循環前被求值。如果求值爲真,statement就會被執行。如果求值爲假,則跳出while循環執行後面的語句
statement:
只要條件表達式求值爲真,該語句就會一直被執行。要在循環中執行多條語句,可以使用塊語句({ ... })包住多條語句
注意:使用break語句在條件表達式計算結果爲真之前停止循環
如下代碼所示:求1-100之和
var number = 1; // 循環的初始條件,定義在外面
var sum = 0;
function getSum(n){
while(number<n) { // 循環滿足什麼條件時執行
sum += number;
++number; // 循環變量的更新
}
return sum;
}
getSum(100);
複製代碼
使用while循環的時候,需要注意幾點:
- 循環的初始條件是定義在外面的
- 只有while中條件表達式爲真時,才執行裏面的語句體
- while循環中應該有循環變量的更新,否則它會造成死循環
do...while循環
創建一個執行指定語句的循環,直到條件表達式值爲false。在執行statement 後檢測條件表達式,所以指定的statement至少執行一次
寫法:
do {
語句體;
}while(條件表達式循環條件)
複製代碼
使用場景: 往往需要一開始就要執行一次,就像很多遊戲一樣,一上來,就讓你先玩一盤,闖過了多少關,才進行下一環節。
與while的區別是:
-
whle循環是先判斷後執行,而do..while是先執行,後判斷
-
當第一次條件不成立時,while不會執行,而do-while無論是否成立都至少會執行一次
-
循環中每次都會計算的表達式。如果條件表達式循環條件值爲真, 語句體會再次執行。當條件表達式循環條件值爲假,則跳到do...while之後的語句
例如將while
語句改成do..while
寫法
var number = 1;
var sum = 0;
function getSum(n) {
do {
sum += number;
++number;
} while (number < n);
return sum;
}
console.log(getSum(3));
複製代碼
for循環
用於創建一個循環,它包含了三個可選的表達式,這三個表達式被包圍在圓括號之中,使用分號分隔,後跟一個用於在循環中執行的語句
應用場景:用於固定循環次數的場景
寫法:
for(初始化變量;循環條件;循環自增變量){
循環體;
}
複製代碼
注意事項:
-
for 語句頭部圓括號中的所有三個表達式都是可選的
-
初始化值可以定義在圓括號裏頭,也可以定義在外頭,但是個人強烈建議定義在裏頭,不要寫讓人猜的代碼,更不要寫奇奇怪怪的代碼,讓人看不懂,不是在炫技,而是在挖坑,本質上就是垃圾代碼
var sum = 0;
function getSum(n) {
for (var number = 0; number < n; number++) {
sum += number;
}
return sum;
}
console.log(getSum(100))
複製代碼
for循環往往是在我們已知循環次數的情況下使用它,常用於遍歷數組
小結:
- for循環擁有三個表達式的語法結構,得給定初始條件,條件判斷、自增變量,它是在已經知道循環次數的情況下使用它
- while循環是先判斷後執行,表達式中只有一個boolean類型的值用於作爲循環結束的判斷,若表達式爲真,則執行語句體,若爲假,則跳出while循環,它常用於:不知道循環執行的次數,只知道達到某個條件的時候循環繼續時使用
do- while
循環是while
循環的變形,在語法上與while
有相似度,它是先執行後判斷,判斷循環是否繼續執行的boolean
表達式放在了循環體的後面,它也是在不知道循環執行的具體次數,只知道達到某個條件時循環繼續或結束,但,至少執行一次
當然針對for
循環常常用於遍歷,可以用forEach
,map
等一些迭代器方法替代的
表達式中的真(true)與(false)假
在上面的if語句,while
語句,do..while
,以及for
循環,都離不開條件表達式,而條件表達式的結果,毫無疑問,影響着語句體的執行,下面這些實際開發中的技巧有必要提一嘴
下⾯的布爾表達式都返回 false:
- null
- undefined
- 0 // 數字0
- “” // 空字符串
- NaN 怎麼檢測:可以利用系統內置對象Boolean(),它會返回一個布爾值,注意這個Boolean的作用是用來初始化 Boolean 對象的值的
但是要注意:下面的都返回true
- "0"; // 字符串0
- []; // 空數組
- {}; // 空對象
- 非0數字
- Infinity
注意:任何不是null 和undefined包括值爲 false 的 Boolean 對象,直接用於條件語句時都會被當做 true 來對待,有new時,會執行語句體的代碼,而無new則不會執行語句體的代碼
var x = new Boolean(false);
if (x) {
// 這裏的代碼會被執行
}
複製代碼
基本類型的布爾值不受此規則影響,如下代碼
var x = false;
if (x) {
// 這裏的代碼不會執行
}
複製代碼
注意:不要用創建 Boolean 對象的方式將一個非布爾值轉化成布爾值,直接將Boolean
當做轉換函數來使用即可,或者使用雙重!!運算符
var x = Boolean(expression); // 推薦
var x = !!(expression); // 推薦
var x = new Boolean(expression); // 不太好
複製代碼
有new
與無new
的結果是不一樣的,前面無new
的Boolean
會返回一個boolean
結果 值得注意的是:
對於任何對象,即使是值爲false
的 Boolean
對象,當將其傳給Boolean
函數時,生成的Boolean
對象的值都爲true
,如下所示
var myFalse = new Boolean(false); // false
var g = new Boolean(myFalse); // true
var myString = new String("Hello");
var s = new Boolean(myString); // true
if (myFalse) {
console.log("itclanCoder"); // 這條語句會執行
}
複製代碼
官方的建議是:不要在應該使用基本類型布爾值的地方使用 Boolean
對象,濫用Boolean
對象,如果需要將其他類型轉化爲布爾值的時候,可以使用,例如將字符串轉爲boolean
類型等
以下是列出的值得注意
Boolean('0') == true; // true
'0' != true // true
0 != null ; // true
0 == [] ; // true,比較的是值,如果是全等===,那麼將是false
0 == false // true
Boolean(null) == false; // true
null != true; // true
null != false // true
Boolean(undefined) == false; // true
undefined != true; // true
undefined != false; // true
Boolean([]) == true // true
Boolean({}) == true // true
複製代碼
有時候,當你需要排除不是0和空字符和false,或許你會寫這樣的代碼
if (x != "" && x != null) {
// 語句體
}
複製代碼
上面的代碼不是不可以,但很冗餘,可以優化爲如下所示
if (x) {
// 語句體
}
複製代碼
當你使用while循環時,當你希望 變量x 不是 0 和空字符串, 和 false,你或許看到這樣的代碼
while(x != null){
// 語句體
}
複製代碼
同樣,可以優化爲如下所示
while(x) {
// 語句體
}
複製代碼
面的代碼優化同時考慮到了null,空字符,或者false的情況,如果說要非真的話,那麼就取反嘛
結語
本小節主要學習到js中的選擇控制語句,if語句,switch語句,while語句以及do..while語句,for循環的對比,每個語句都有與之對應的應用場景以及解決的問題,比較基礎