while
while
语句创建一个循环,只要测试条件计算结果为真,就执行指定的语句。在执行语句之前会评估条件。
试试看
语法
描述
示例
使用 while
以下while
循环只要n
小于三就迭代。
js
let n = 0;
let x = 0;
while (n < 3) {
n++;
x += n;
}
每次迭代,循环都会递增n
并将其添加到x
。因此,x
和n
将取以下值
- 第一次执行后:
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()) {
该行的效果很好——也就是说,每次找到一个注释节点时
iterator.nextNode()
返回该注释节点,该节点被分配给currentNode
。- 因此,
currentNode = iterator.nextNode()
的值为真值。 - 因此,
console.log()
调用执行并且循环继续。
……然后,当文档中没有更多注释节点时
这行代码的问题在于:条件通常使用比较运算符(如===
),但该行中的=
不是比较运算符——而是赋值运算符。因此,该=
看起来像是===
的错别字——即使它实际上不是错别字。
因此,在像那种情况下,一些代码 lint 工具(例如 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 语言规范 # sec-while-statement |
浏览器兼容性
BCD 表格仅在浏览器中加载