重學前端學習筆記(三十一)--JavaScript的語句

筆記說明

重學前端是程劭非(winter)【前手機淘寶前端負責人】在極客時間開的一個專欄,天天10分鐘,重構你的前端知識體系,筆者主要整理學習過程的一些要點筆記以及感悟,完整的能夠加入winter的專欄學習【原文有winter的語音】,若有侵權請聯繫我,郵箱:kaimo313@foxmail.com。前端

1、介紹

在 JavaScript 標準中,把語句分紅了兩種:普通語句和聲明型語句。數組

1.一、普通語句

普通語句

1.二、聲明型語句

聲明型語句

2、語句塊

語句塊就是一對大括號。異步

{
    var x, y;
    x = 10;
    y = 20;
}
複製代碼

語句塊的意義和好處在於:讓咱們能夠把多行語句視爲同一行語句。async

// 語句塊會產生做用域
{
    let x = 1;
}
console.log(x); // Uncaught ReferenceError: x is not defined
複製代碼

3、空語句

空語句就是一個獨立的分號,實際上沒什麼大用。函數

;
複製代碼

4、if 語句

if(a < b)
    console.log(a);
複製代碼

if 和 else 連寫成多分支條件學習

if(a < 10) {
   //...
} else if(a < 20) {
   //...
} else if(a < 30) {
   //...
} else {
   //...
}
複製代碼

5、switch 語句

switch(num) {
case 1:
    console.log(1);
case 2:
    console.log(2);
case 3:
    console.log(3);
}
// num等於1,輸出:1 2 3
// num等於2,輸出:2 3
// num等於3,輸出:3

switch(num) {
case 1:
    console.log(1);
    break;
case 2:
    console.log(2);
    break;
case 3:
    console.log(3);
    break;
}
// num等於1,輸出:1
// num等於2,輸出:2
// num等於3,輸出:3
複製代碼

winter 的見解是:「 switch 已經徹底沒有必要使用了,應該用 if else 結構代替。」。ui

6、循環語句

6.一、while 循環和 do while 循環

let a = 5;
while(a--) {
    console.log("*");
}
// 輸出:* * * * *
複製代碼
let a = 6;
do {
    console.log(a);
} while(a < 6)
// 6
複製代碼

6.二、普通 for 循環

for(i = 0; i < 6; i++)
    console.log(i);
// 0 1 2 3 4 5

for(var i = 0; i < 6; i++)
    console.log(i);
// 0 1 2 3 4 5

for(let i = 0; i < 6; i++)
    console.log(i);
// 0 1 2 3 4 5

for(const i = 0; i < 6; i++)
    console.log(i);
// 0 Uncaught TypeError: Assignment to constant variable.

var j = 0;
for(const i = 0; j < 6; j++)
    console.log(i);
// 0 0 0 0 0 0
複製代碼

6.三、for in 循環

for in 循環枚舉對象的屬性,體現了屬性的 enumerable 特徵。this

let o = { a: 10, b: 20}
Object.defineProperty(o, "c", {enumerable: false, value: 30})

for(let p in o)
    console.log(p);
// 輸出:a b
// enumerable爲true,輸出:a b c
複製代碼

6.四、for of 循環和 for await of 循環

for of 循環是很是棒的語法特性。背後的機制是 iterator 機制。spa

一、用於數組debug

for(let e of [1, 2, 3, 4, 5])
    console.log(e);
// 1 2 3 4 5
複製代碼

二、如何爲一個對象添加 iterator

let o = {  
    [Symbol.iterator]:() => ({
        _value: 0,
        next(){
            if(this._value == 10)
                return {
                    done: true
                }
            else return {
                value: this._value++,
                done: false
            };
        }
    })
}
for(let e of o)
    console.log(e);
// 0 1 2 3 4 5 6 7 8 9
複製代碼

三、使用 generator function

function* foo(){
    yield 0;
    yield 1;
    yield 2;
    yield 3;
}
for(let e of foo())
    console.log(e);
// 0 1 2 3
複製代碼

四、JavaScript 還爲異步生成器函數配備了異步的 for of

function sleep(duration) {
    return new Promise(function(resolve, reject) {
        setTimeout(resolve,duration);
    })
}
async function* foo(){
    i = 0;
    while(true) {
        await sleep(1000);
        yield i++;
    }
}
for await(let e of foo())
    console.log(e);
// 從0開始,每隔1s加1,輸出:0 1 2 3 4 5....
複製代碼

7、return

return 語句用於函數中,它終止函數的執行,而且指定函數的返回值。

function squre(x){
    return x * x;
}
複製代碼

8、break 語句和 continue 語句

break 語句用於跳出循環語句或者 switch 語句,continue 語句用於結束本次循環並繼續循環。

for(let i = 0; i < 2; i++){
    console.log(i)
    if( i == 0){
        break;
    }
}
// 0

for(let i = 0; i < 2; i++){
    console.log(i)
    if( i == 0){
        continue;
    }
}
// 0 1
複製代碼

9、with 語句

with 語句把對象的屬性在它內部的做用域內變成變量。

let o = {a:1, b:2}
with(o){
    console.log(a, b);
}
// 1 2
複製代碼

10、try 語句和 throw 語句

try 語句和 throw 語句用於處理異常。try 語句用於捕獲異常,用 throw 拋出的異常。

  • try 部分用於標識捕獲異常的代碼段
  • catch 部分則用於捕獲異常後作一些處理(catch結構會建立一個局部的做用域,不能再聲明變量 e ,不然會出錯。)
  • finally 語句通常用於釋放資源,它必定會被執行
try {
    throw new Error("error");
} catch(e) {
    console.log(e);
} finally {
    console.log("finally");
}
// Error: error at <anonymous>:2:1 
// finally
複製代碼

11、debugger 語句

debugger 語句的做用是:通知調試器在此斷點。在沒有調試器掛載時,它不產生任何效果。

12、var

一、var 聲明語句是古典的 JavaScript 中聲明變量的方式。而如今,基本使用 let 和 const 。

二、若是仍然想要使用 var,winter建議:把它當作一種保障變量是局部的邏輯,遵循如下三條規則:

  • 聲明同時一定初始化
  • 儘量在離使用的位置近處聲明
  • 不要在乎重複聲明
// 下面這裏x聲明瞭兩次
function add(x,y) {
    console.log(x + y);
}
function multiply(x,y) {
    console.log(x * y);
}

var x = 1, y = 2;
add(x, y);

for(var x = 0; x < 2; x++)
    multiply(x,y);
// 3
// 0
// 2

// 使用let改造,用代碼塊限制了第一個 x 的做用域,這樣就更難發生變量命名衝突引發的錯誤。
{
    let x = 1, y = 2;
    add(x, y);
}

for(let x = 0; x < 2; x++)
    multiply(x);
複製代碼

十3、let 和 const

const a = 2;
if(true){
    const a = 1;
    console.log(a);
}
console.log(a);
// 1 2
複製代碼

一、const 和 let 語句在重複聲明時會拋錯,這可以有效地避免變量名無心中衝突。

let a = 2
const a = 1;
// Uncaught SyntaxError: Identifier 'a' has already been declared
複製代碼

二、let 和 const 聲明仍是會被預處理。若是當前做用域內有聲明,就沒法訪問到外部的變量。

const a = 2;
if(true){
    console.log(a); // 拋錯
    const a = 1;
}
// Uncaught ReferenceError: Cannot access 'a' before initialization

if(true){
    console.log(a);
   var a = 1;
}
// undefined

// 上面的對比就說明 const 聲明仍然是有預處理機制的。
複製代碼

十4、class 聲明

class 最基本的用法只須要 class 關鍵字、名稱和一對大括號。

一、class 的聲明特徵跟 constlet 相似,都是做用於塊級做用域,預處理階段則會屏蔽外部變量。

const a = 2;
if(true){
    console.log(a); // 拋錯
    class a {

    }
}
// Uncaught ReferenceError: Cannot access 'a' before initialization
複製代碼

二、class 內部,可使用 constructor 關鍵字來定義構造函數。

// 這個例子來自 MDN,它展現了構造函數、getter 和方法的定義。
class Rectangle {
  constructor(height, width) {
    this.height = height;
    this.width = width;
  }
  // Getter
  get area() {
    return this.calcArea();
  }
  // Method
  calcArea() {
    return this.height * this.width;
  }
}
複製代碼

十5、函數聲明

函數聲明使用 function 關鍵字。

一、帶 * 的函數是 generator。生成器函數能夠理解爲返回一個序列的函數,它的底層是 iterator 機制。

二、async 函數是能夠暫停執行,等待異步操做的函數,它的底層是 Promise 機制。

function foo(){

}

function* foo(){
    yield 1;
    yield 2;
    yield 3;
}

async function foo(){
    await sleep(3000);
}

async function* foo(){
    await sleep(3000);
    yield 1;
}
複製代碼

三、函數的參數,能夠只寫形參名,還能夠寫默認參數和指定多個參數

function foo(a = 1, ...other) {
    console.log(a, other)
}

foo();
// 1 []

foo(3,4);
// 3 [4]
複製代碼

我的總結

用的少的須要增強一下,對於底層的東西實在瞭解的太少。。。

相關文章
相關標籤/搜索