while

Baseline 已廣泛支援

此特性已相當成熟,可在許多裝置和瀏覽器版本上使用。自 ⁨2015 年 7 月⁩以來,各瀏覽器均已提供此特性。

while 語句建立一個迴圈,只要測試條件評估為真,就會執行指定的語句。條件在執行語句之前進行評估。

試一試

let n = 0;

while (n < 3) {
  n++;
}

console.log(n);
// Expected output: 3

語法

js
while (condition)
  statement
條件

在每次迴圈透過之前評估的表示式。如果此條件評估為真,則執行 statement。當條件評估為假時,執行將繼續 while 迴圈之後的語句。

statement

只要條件評估為真,就執行的語句。您可以使用塊語句來執行多個語句。

描述

像其他迴圈語句一樣,你可以在 statement 中使用控制流語句

  • break 會停止 statement 的執行,並跳轉到迴圈之後的第一條語句。
  • continue 停止 statement 執行並重新評估 condition

示例

使用 while

以下 while 迴圈只要 n 小於 3 就會迭代。

js
let n = 0;
let x = 0;

while (n < 3) {
  n++;
  x += n;
}

每次迭代,迴圈都會增加 n 並將其新增到 x。因此,xn 的值如下

  • 第一次通過後:n = 1 和 x = 1
  • 第二次通過後:n = 2 和 x = 3
  • 第三次通過後:n = 3 和 x = 6

完成第三次通過後,條件 n < 3 不再為真,因此迴圈終止。

使用賦值作為條件

在某些情況下,將賦值作為條件可能是有意義的。這會帶來可讀性方面的權衡,因此有一些樣式建議可以使該模式對所有人來說更明顯。

考慮以下示例,它迭代文件的註釋,並將它們記錄到控制檯。

js
const iterator = document.createNodeIterator(document, NodeFilter.SHOW_COMMENT);
let currentNode;
while (currentNode = iterator.nextNode()) {
  console.log(currentNode.textContent.trim());
}

這並不是一個完全好的實踐示例,特別是由於以下行

js
while (currentNode = iterator.nextNode()) {

該行的效果很好——每次找到註釋節點時

  1. iterator.nextNode() 返回該註釋節點,該節點被賦值給 currentNode
  2. 因此,currentNode = iterator.nextNode() 的值是真值
  3. 因此 console.log() 呼叫執行並且迴圈繼續。

……然後,當文件中沒有更多註釋節點時

  1. iterator.nextNode() 返回null
  2. 因此,currentNode = iterator.nextNode() 的值也是 null,這是假值
  3. 所以迴圈結束。

該行的問題是:條件通常使用比較運算子,例如 ===,但該行中的 = 不是比較運算子,而是賦值運算子。因此,那個 = 看起來像=== 的錯字——儘管它實際上不是錯字。

因此,在這種情況下,一些程式碼檢查工具(例如 ESLint 的no-cond-assign 規則)為了幫助您發現可能的錯字以便您可以修復它,將報告以下警告

期望條件表示式,卻看到了賦值。

許多樣式指南建議更明確地指示條件為賦值的意圖。您可以透過將額外的括號作為分組運算子放在賦值周圍來最小化地做到這一點

js
const iterator = document.createNodeIterator(document, NodeFilter.SHOW_COMMENT);
let currentNode;
while ((currentNode = iterator.nextNode())) {
  console.log(currentNode.textContent.trim());
}

事實上,這是 ESLint 的 no-cond-assign 的預設配置以及 Prettier 所強制的樣式,因此您可能會在實際專案中經常看到這種模式。

有些人可能還會建議新增比較運算子,將條件變成明確的比較

js
while ((currentNode = iterator.nextNode()) !== null) {

還有其他方法可以編寫這種模式,例如

js
while ((currentNode = iterator.nextNode()) && currentNode) {

或者,完全放棄使用 while 迴圈的想法

js
const iterator = document.createNodeIterator(document, NodeFilter.SHOW_COMMENT);
for (
  let currentNode = iterator.nextNode();
  currentNode;
  currentNode = iterator.nextNode()
) {
  console.log(currentNode.textContent.trim());
}

如果讀者對賦值作為條件模式足夠熟悉,所有這些變體都應該具有相同的可讀性。否則,最後一種形式可能是最可讀的,儘管它最冗長。

規範

規範
ECMAScript® 2026 語言規範
# sec-while-statement

瀏覽器相容性

另見