async & defer

async (非同步)

現在許多 Web API 功能都是使用非同步程式碼的做法,特別是那些要從外部裝置存取或抓取某些種類資源的功能,像是從網路抓取檔案、存取資料庫並回傳資料、從網路攝影機取得視訊串流或者是將畫面透過廣播的方式顯示到 VR 頭盔等。

為什麼同步的程式碼很難做到這些事?我們快速地看個例子。當你想要從伺服器抓取一張影像,你是沒有辦法馬上獲得結果的。這個意思是下面的程式碼(虛擬碼)是行不通的:

let response = fetch('myImage.png'); // fetch is asynchronous
let blob = response.blob();
// display your image blob in the UI somehow

那是因為你不知道下載影像需要花上多少時間,所以當執行第二行時它將拋出一段錯誤(也許間歇性的發生,也許每一次都發生)這是因為 response 尚未取得結果還不能使用。因此在它嘗試做接下來的任何事之前,你需要讓你的程式碼先等到 response 回傳結果。最佳使用情境,是當網頁中的腳本間彼此獨立,因而不依賴彼此運行的狀況下。

defer  屬性(如下所示)所載入的腳本,會在腳本與內容都下載完成後,依照出現順序被執行。

在網頁的所有內容被載入完成之前,它是不會被執行的。當你的程式依賴著某些元素存在時(如:要調整頁面上一到多個元素),這個屬性很有用。

<script defer src="js/vendor/jquery.js"></script>

<script defer src="js/script2.js"></script>

<script defer src="js/script3.js"></script>

var 與 let/const 差別

/// 「var」 不受區塊限制,區塊外變數存取成功。///

{
  var corgiDogName = '吐司';
}

console.log(corgiDogName);
//吐司
///「let」會受區塊限制,區塊外變數存取失敗。///
{
  let corgiDogName = '吐司';
}

console.log(corgiDogName);
//ReferenceError: corgiName is not defined

var不受區塊限制,但會受到函式範圍限制

/// 「var」 受函式限制,函式外變數存取失敗。///

function callCorgi() {
  var corgiDogName = '吐司';
}

console.log(corgiDogName);
//ReferenceError: corgiDogName is not defined
/// 即使用 var 宣告相同的變數名稱 dogName,但因為「 函式作用域 」,所以不會讓同名變數衝突。 ///

//將柯基犬命名為吐司,之後用 callCargi() 呼叫
function callCargi() {
  var dogName = '吐司';
  console.log(dogName);
}

//將米克斯犬命名為厚片,之後用 callMix() 呼叫
function callMix() {
  var dogName = '厚片';
  console.log(dogName);
}

callCargi(); //吐司
callMix(); //厚片

var 與 let / const 差異總結

  1. var 屬於函式作用域,let/const屬於區域作用域,後者能避免更多情況下的同名變數與提取變數衝突、區塊內變數污染到全域的情況,且讓 for loop 使用更直覺方便。
  2. var 會自動提升變數,let/const 則較為嚴謹,後者能避免忘記宣告變數或因無宣告讓變數污染到全域的情況。
  3. var 能重複宣告同名變數,let/const 不能重複宣告同名變數,後者能避免些開發上的錯誤情況。

綜合來說就是 let/const 將宣告變數變得更加嚴謹,藉此增加易讀性、防止出錯,而最重要的 CTA ,我想就是: