语句

208 阅读2分钟

if 语句

  • if (condition) statement1 else statement2
  • 条件可以是任何表达式,结果不一定是布尔值。ECMA 会自动调用 Boolean() 函数转换
  • 连续 if 语句用 else if
if (1 === 2) {
  console.log(1);
} else if (1 === 3) {
  console.log(2);
} else {
  console.log(3);
}

do-while 语句

  • 后测试循环语句,循环体中代码执行后才会对退出条件求值
  • 先执行后判断,循环体内的代码至少执行一次
do {
  statement
} while (expression);

let i = 0;
do {
  i += 2;
} while (i > 10);
console.log(i); // 2

while 语句

  • while (expression) statement
  • 先测试循环语句,先检测退出条件,再执行循环体内的代码
let i = 0;
while (i > 10) {
  i += 2;
}
console.log(i); // 0

for 语句

  • for (initialization; expression; post-loop-expression) statement
  • 先测试循环语句,增加了进入循环前的初始化代码,及循环执行后要执行的表达式
const count = 10;
for (let i = 0; i < count; i++) {
  console.log(i);
}
  • 类比 while 循环,相当于
let count = 10;
let i = 0;
while (i < count) {
    console.log(i);
    i++;
}
  • 无法通过 while 循环实现的逻辑,同样也无法使用 for 循环实现,他只是将相关的循环代码封装在一起而已
  • 可以不适用变量声明关键字,不过,初始化定义的迭代器变量在循环执行完成后几乎不可能再用了,所以用 let 声明迭代器变量是最清晰的,这样就可以将这个变量的作用域限定在循环中
const btn = document.querySelectorAll('button');
for (let i = 0; i < btn.length; i++) { // 使用 var 试试看区别
  btn[i].onclick = () => {
    console.log(i);
  }
}
  • 初始化、条件表达和循环后表达都不是必需的,for (;;) doSomething 河阳可以无穷循环

for-in 语句

  • for (property in expression) statement
  • 严格的迭代语句,用于枚举对象中的非符号键属性
for (const propName in window) {
	document.write(propName)
}
  • 这个例子使用 for-in 显示了 window 对象的所有属性。每次循环都会给 propName 赋予一个 window 对象的属性作为值,直到所有属性都被枚举一遍。为了确保这个局部变量不被修改,推荐使用 const
  • ECMA 的对象属性是无序的,因此 for-in 语句不能保证返回对象属性的顺序,可能会因浏览器有差异
  • 如果 for-in 循环要迭代的变量是 nullundefined,则不执行循环体

for-of 语句

  • for (property of expression) statement
  • 严格的迭代语句,用于遍历可迭代对象的元素
for (const el of [2, 4, 6, 8]) {
  document.write(el);
}
  • 循环会一直持续到将所有元素迭代完,const 不是必需的,但为了确保这个局部变量不被修改,推荐使用 const
  • for-of 循环会按照可迭代对象的 next() 方法产生值的顺序迭代元素
  • 如果尝试迭代的变量不支持迭代,则 for-of 语句会抛出错误

标签语句

  • label: statement
  • 标签语句用于给语句加标签
start: for (let i = 0; i < count; i++) {
    console.log(i);
}
  • 上面例子中,start 是一个标签,可以再后面通过 breakcontinue 语句引用。标签语句的典型应用场景是嵌套循环

break 和 continue 语句

  • 执行循环代码中的更严格的控制手段
  • break:立即退出循环,强制执行循环后的下一条语句 - 结束整个循环
  • continue:立刻退出循环,但会再次从循环顶部开始执行 - 跳出当前循环
let num1 = 0;
for (let i = 1; i < 10; i++) {
  if (!(i % 5)) {
    break;
  }
  num1++;
}
console.log(num1); // 4

let num2 = 0;
for (let i = 1; i < 10; i++) {
  if (!(i % 5)) {
    continue;
  }
  num2++;
}
console.log(num2); // 8
  • breakcontinue 都可以与标签语句一起使用,返回代码中特定的位置,通常在嵌套循环中使用
let num1 = 0;
outermost:
for (let i = 0; i < 10; i++) {
  for (let j = 0; j < 10; j++) {
    if (i === 5 && j === 5) {
      break outermost;
    }
    num1++;
  }
}
console.log(num1); // 55

let num2 = 0;
outermost:
for (let i = 0; i < 10; i++) {
  for (let j = 0; j < 10; j++) {
    if (i === 5 && j === 5) {
      continue outermost;
    }
    num2++;
  }
}
console.log(num2); // 95
  • 这个例子中,outermost 标签识别的是第一个 for 语句,breakcontinue 带出了一个变量(要退出到的标签)。添加标签不仅退出内部循环(变量 j),也会退出外部循环(变量 i
  • 组合使用标签语句和 breakcontinue 能实现复杂的逻辑,但也容易出错。注意标签要使用描述性强的文本,而嵌套也不要太深

with 语句

  • with (expression) statement
  • 将代码作用域设置为特定的对象
const qs = location.search.substring(1);
const hostName = location.hostname;
const url = location.href;
// 每一行都用到了 location 对象,如果使用 with 语句,就可以少写一些代码
with (location) {
  const qs = search.substring(1);
  const hostName = hostname;
  const url = href;
}
  • 这里,with 语句用于连接 location 对象。这意味着再这个语句内部,每个变量首先会被认为是一个局部变量。如果没有找到该局部变量,则会搜索 location 对象,看它是否有一个同名的属性。如果有,则该变量会被求值为 location 对象的属性
  • 严格模式不允许使用 with 语句,否则会抛出错误
  • 警告由于 with 语句影响性能且难于调试其中代码,通常不推荐再产品代码中使用 with 语句

switch 语句

  • switch 语句是与 if 语句紧密相关的一种流控制语句
switch (expression) {
  case value1:
    statement
    break;
  case value2:
    statement
    break;
  default:
    statement
}
  • 每个 case(条件/分支)相当于:如果表达式等于后面的值,则执行下面的语句
  • break 关键字会导致代码执行跳出 switch 语句,如果没有 break,则代码会继续匹配下一个条件
  • default 关键字用于任何条件都没有满足时指定默认执行的语句
switch (i) {
  case 25:
    console.log(25);
    break;
  case 35:
    console.log(35);
    break;
  case 45:
    console.log(45);
    break;
  default:
    console.log('other');
}
// 用 if 表达
if (i === 25) {
  console.log(25);
} else if (i === 35) {
  console.log(35);
} else if (i === 45) {
  console.log(45);
} else {
  console.log('other');
}
  • switch 语句可以用于所有数据类型(再很多语言中,它只能用于数值),因此可以使用字符串甚至对象。其次,条件的值不需要时常量,也可以时变量或表达式
switch ('hello world') {
  case 'hello' + ' world':
    console.log('Greeting was found.');
    break;
  case 'goodbye':
    console.log('Closing was found.');
    break;
  default:
    console.log('Unexpected message was found.');
}
  • 在条件判断中使用表达式,就可以在判断中加入更多逻辑,也能清晰展示
let num = 25;
switch (true) {
  case num < 0:
    console.log('Less than 0.');
    break;
  case num >= 0 && num <= 10:
    console.log('Between 10 and 20.');
    break;
  default:
    console.log('More than 20.');
}
  • 上面的代码中,条件为 true,代码从上至下执行,条件表达式分别被求值,知道有表达式返回 true,否则,就会一直跳到 default 语句
  • 注意switch 语句在比较每个条件的值时会使用全等操作符,因此不会强制转换数据类型('10' !== 10)