網站搜尋

為什麼 TypeScript 編譯器不會提升變數?


我理解 ES6 和 TypeScript 都支持區塊級作用域,但在針對 ES3 和 ES5 時,輸出應該是函數級作用域。我認為 TypeScript 不提升變數一定有其背後的邏輯……而我並不是遇到問題,我只是對為什麼它不提升變數感到好奇。

例如,給定以下 TypeScript:

function seed(length: number, multiplier: number): number[] {
  let result: number[] = [];

  for(let i: number = 0; i < length; i++) {
    let n: number = i * multiplier;

    result.push(n);
  }

  return result;
}

轉譯器輸出:

function seed(length, multiplier) {
  var result = [];
  for (var i = 0; i < length; i++) {
    var n = i * multiplier;
    result.push(n);
  }
  return result;
}

我原本預期的結果是變數宣告會被提升到函式的頂部。大概看起來像這樣:

function seed(length, multiplier) {
  var
    i, n,
    result = [];

  for (i = 0; i < length; i++) {
    n = i * multiplier;
    result.push(n);
  }
  return result;
}

任何見解都非常感謝。謝謝!

答案#1

這是因為編譯器不會根據程式碼標準輸出程式碼。它會盡可能接近原始輸入。

請注意,var 變數無論如何都會在幕後被提升(var 提升)。在這種情況下,TypeScript 編譯器沒有必要更改輸入,這樣做只會無謂地增加其複雜性。

答案#2

我認為 TypeScript 不提升變數一定有其背後的邏輯……我並不是遇到什麼問題,我只是對它為什麼不提升變數感到好奇。

正是如此。因為這根本不是問題,為什麼還要費心去提升呢?

同樣地,如果是 let 的情況,像你所示那樣提升它實際上是錯誤的。

暫時性死區

首先,let 變數不能像 var 變數那樣在宣告之前使用。使用 var 時,你會得到 undefined。使用 let 時,由於暫時性死區,你會得到 ReferenceError。幸運的是,TypeScript 無論如何會在編譯時給你一個錯誤,因此你不會在執行時遇到這個問題。

console.log(a); // Error: Block scoped variable used before declaration 
let a = 123;

區塊作用域

let 在 for 迴圈中宣告的變數 僅在 該迴圈中可用。這是因為它們是 區塊作用域 而非 函式作用域。更多相關資訊

同樣地,如果你誤用 let,TypeScript 會在編譯時給你錯誤提示(而不是等到執行時才遇到問題):

for(let i: number = 0; i < 10; i++) {    
}  
console.log(i); // Error: no variable i in scope

希望這有幫助 🌹