腦圖學習 JavaScript 之犀牛書【五】語句

ZxBing0066發表於2019-12-04

介紹

第五章主要講解 JavaScript 中的語句,其中主要內容涉及到 迴圈語句、跳轉標籤、跳轉語句、try/catch、嚴格模式

自我提問

  • 什麼是跳轉標籤,使用場景是什麼?

  • 下面的程式碼執行後會怎樣列印?

    (function() {
        try {
            console.log('return');
            return;
        } catch (error) {
        } finally {
            console.log('finally');
        }
    })();
    console.log('end');
    複製程式碼
    const a = 1;
    switch (a) {
        case '1':
            console.log(1);
        case 1:
            console.log(2);
        case 2:
            console.log(3);
        case 3:
            console.log(4);
            break;
        default:
            console.log(5);
    }
    複製程式碼
  • 執行下面的 for/in 語句會發生什麼?

    const o = { x: 1, y: 2, z: 3 },
        a = [];
    let i = 0;
    for (a[i++] in o);
    複製程式碼
    for(let a in null) {
        console.log(1);
    }
    複製程式碼
  • 嚴格模式有什麼特點?

腦圖

腦圖學習 JavaScript 之犀牛書【五】語句

關鍵知識點

語句的定義

語句是整句或命令。表示式用來計算一個值,語句用來執行來使某件事發生

語句型別

表示式語句

具有副作用的表示式是最簡單的語句

空語句

一個 ; 便為一個空語句(按照定義,語句讓某件事情發生,但是空語句什麼都不會發生,這些概念的東西真是看不懂)

複合語句

將多個語句聯合在一起便可形成一條複合語句

宣告語句

var、function 均為宣告語句,但是函式宣告語句不能出現在 if、while 等語句中,所以標準並沒有把函式宣告歸類為真正的語句(感覺有點奇怪,變數宣告和函式宣告都不能出現在 if 的條件判斷中)

條件語句

條件語句包括 if, while,else if 不是單個語句,而是 else 和 if 合併的複合語句

迴圈語句

常見的迴圈語句語句 for、while、do/while、for/in

跳轉語句

常見的跳轉語句有 return、break、continue、throw

其它語句

其它的還有如 with、debugger,('use strict;' 不是語句,而是一個字串直接量指令)

空語句的用法

空語句最常見的用法,是用來初始化一個陣列。

for (i = 0; i < a.length; a[i++] = 0) ;
複製程式碼

switch 語句的注意點

  • switch 中 使用 === 來進行匹配
  • return、break 都可以用來終止 switch
  • switch 匹配後 如果不使用 return、break 中斷,將會一直向下執行所有的 case 中的語句直到最後,俗稱 case 穿透,初用最常見的坑點
const a = 1;
switch (a) {
    case '1':
        console.log(1);
    case 1:
        console.log(2);
    case 2:
        console.log(3);
    case 3:
        console.log(4);
        break;
    default:
        console.log(5);
}
// 2 3 4
複製程式碼

for in 語句注意點

  • for(varible in obj) 中 obj 的值為 null、undefined 時,將會跳過(不會報錯),其它原始值會轉換為對應的包裝物件
  • for/in 只會遍歷可列舉屬性,遍歷過程中刪除的未列舉的屬性,正常將不會被列舉到,新增的屬性正常也不會列舉到
  • 一般瀏覽器會按照屬性定義的前後列舉屬性,但是 不應該依賴 for/in 執行順序
  • varible 可以是 任意左值表示式
const o = { x: 1, y: 2, z: 3 },
    a = [];
let i = 0;
for (a[i++] in o);

console.log(a);
// [ 'x', 'y', 'z' ]
複製程式碼

跳轉標籤

跳轉標籤是一個非常容易被忽略的語法(過於冷門),實際開發中幾乎看不到有人用,不過 在多迴圈巢狀時有奇效

  • 只有 break 和 continue 可以使用標籤
  • 標籤的命名和規則和識別符號相同(字母、_、$ 開頭,後面可以跟數字)
  • 標籤和變數是兩個名稱空間,不會互相沖突
  • 內部的標籤不能和外部標籤重名
  • 一個語句可以有多個標籤
  • 使用標籤,可以讓 break 和 continue 跳過多層巢狀的迴圈體
  • 標籤只在他定義的語句中有定義

使用標籤跳轉來快速結束查詢

const dataSource = new Array(100)
    .fill(null)
    .map((v, i) => new Array(i).fill(null).map((v, i) => new Array(i).fill(null)));

const TARGET = 'TARGET';

dataSource[50][30][20] = TARGET;

const l = dataSource.length;
let count = 0;

let result;
// 為了演示標籤,不寫遞迴
first: outter: parent: for (let i = 0; i < l; i++) {
    count++;

    const x = dataSource[i];
    if (x === TARGET) {
        result = [i];
        break;
    }
    if (Array.isArray(x)) {
        for (let j = 0; j < x.length; j++) {
            count++;

            const y = x[j];
            if (y === TARGET) {
                result = [i, j];
                break first;
            }
            if (Array.isArray(y)) {
                for (let k = 0; k < y.length; k++) {
                    count++;

                    const z = y[k];
                    if (z === TARGET) {
                        result = [i, j, k];
                        break first;
                    }
                }
            }
        }
    }
}

console.log(result);
// [50, 30, 20]
複製程式碼

如果不使用標籤,則需要在每個迴圈體的結尾再多做一次判斷來退出迴圈。

try/catch 注意點

try/catch 語句中哪怕是使用了 return、continue、break 等跳轉,也 一定會先執行完 finally 再執行跳轉到目標語句。

(function() {
    try {
        console.log('return');
        return;
    } catch (error) {
    } finally {
        console.log('finally');
    }
})();
console.log('end');
// return
// finally
// end
複製程式碼

嚴格模式

晚上很多文章講的比較詳細,不細說

  • 禁止使用 with
  • 所有變數需要先宣告
  • 呼叫的非方法函式中的 this 值為 undefined (可用於判斷瀏覽器是否支援嚴格模式)
  • call 和 apply 呼叫函式時,this 值為傳入的第一個引數
  • 只讀屬性賦值、不可擴充套件的物件建立新成員將報錯
  • eval 不能再呼叫程式的上下文宣告變數、定義函式
  • arguments 擁有引數的靜態副本,不會和實參共用引用
  • delete 非法標識將、不可配置的屬性會報錯
  • 物件直接量中定義多個同名屬性會報錯
  • 函式存在多個同名引數會報錯
  • 不允許使用八進位制直接量
  • eval 和 arguments 被作為關鍵字,值不可修改
  • 訪問 arguments.caller arguments.callee 、函式的 caller、arguments 會丟擲型別錯誤

系列文章目錄

  1. 腦圖學習 JavaScript 之犀牛書【一】
  2. 腦圖學習 JavaScript 之犀牛書【二】詞法結構
  3. 腦圖學習 JavaScript 之犀牛書【三 · 一】資料型別
  4. 腦圖學習 JavaScript 之犀牛書【三 · 二】型別轉換、變數
  5. 腦圖學習 JavaScript 之犀牛書【四 · 一】運算子、型別轉換
  6. 腦圖學習 JavaScript 之犀牛書【四 · 二】表示式
  7. 腦圖學習 JavaScript 之犀牛書【五】語句

相關文章