1. 条件判断语句

1.1 if-else

  1. if () {
  2. ...
  3. } else if () {
  4. ...
  5. } else {
  6. ...
  7. }

判断中,如果结果不是布尔值,那么会自动使用 Boolean 方法转换为布尔值
只有 0 / NaN / '' / null /undefined 是 false,其余为 true

BAT 面试题:

  1. var num = parseInt('width: 35.5px');
  2. if (num == 35.5) {
  3. alert(0);
  4. } else if (num == 35) {
  5. alert(1);
  6. } else if (num == NaN) {
  7. alert(2);
  8. } else if (typeof num == 'number') {
  9. alert(3);
  10. } else {
  11. alert(4);
  12. }
  13. //=> '3'

typeof

在 JS 中用来检测数据类型的四种方式;

  • typeof

  • instanceof

  • constructor

  • Object.prototype.toString.call()

  1. // 语法:typeof [value]
  2. typeof 12 // 'number'
  3. typeof NaN // 'number'
  4. typeof 'aa' // 'string'
  5. typeof true // 'boolean'
  6. typeof null // 'object' 因为 null 代表空对象指针(没有指向任何内存空间)
  7. typeof {} // 'object'
  8. typeof [] // 'object'
  9. typeof undefined // 'undefined'
  10. typeof Object // 'function'
  11. // 返回值:检测结果是一个字符串,字符串中包含着对应的数据类型,如:'number'/'string'/'object'/'boolean'/'undefined'/'function'
  12. typeof 检测数组/正则/对象,都是返回 'object',也就是无法细分对象

面试题

  1. console.log(typeof typeof []); //=> 'string'

1.2 三元运算符

语法:条件 ? 成立执行 : 不成立执行
相当于最简单的 if/else 判断

  1. var num = 12;
  2. if (num > 10) {
  3. num++;
  4. } else {
  5. num--;
  6. }
  7. //=> 改写成三元运算符
  8. num > 10 ? num++ : num--

特殊情况

  1. //=> 如果三元运算符中的某一部分不需要任何处理,我们使用 null / undefined / void 0 /... 占位即可
  2. var num = 12;
  3. num > 10 ? num++ : ; //=>报错
  4. num > 10 ? num++ : null;
  5. //=> 如果需要执行多项任务,我们把其用小括号包裹起来,每条操作语句用逗号隔开
  6. num > 10 ? (num++, num*=10) : null;

思考题:

  1. var num = 12;
  2. if (num > 0) {
  3. if (num < 10) {
  4. num++;
  5. } else {
  6. num--;
  7. }
  8. } else {
  9. if (num == 0) {
  10. num++;
  11. num /= 10;
  12. }
  13. }
  14. //=> 改为三元运算符
  15. num > 0 ? (num < 10 ? num++ : num--) : (num==0 ? (num++, num/=10) : null);

1.3 switch case

switch 语句中,每个 case 的值可以使用任何数据类型,而且不一定是常量,可以是变量,甚至是表达式。

  1. switch (expression) {
  2. case value1: statement1
  3. break;
  4. case value2: statement2
  5. break;
  6. case value3: statement3
  7. break;
  8. default: statement4
  9. }

switch 语句中的每一种情况 case 的含义是:如果表达式 expression 等于这个值 value ,则执行后面的语句 statement。

break 关键字作用是使代码执行流跳出 switch 语句,如果没有 break,就会在执行完当前 case 后,继续执行下一个 case

default 关键字则用于在表达式不匹配前面的任何一种情况的时候,执行机动代码,default 后面语句执行完不需要再加上 break 了,因为语句已经结束了。default 不是必须的,但是建议使用

switch case 应用于变量(或表达式等)在不同值情况下的不同操作。每一种 case 操作后都要加 break(结束整个判断),除非要合并两种情况。

注意:switch 语句在比较 expression 和 value 的值时使用的是全等操作符,所以不会发生类型转换

  1. '10' == 10 //=> true 相等比较,如果等号两边的类型不一样,首先转换为一样的数据类型,然后再比较
  2. '10' === 10 //=> false 严格相等,只有当类型和值都一样时,结果才是 true

在真实项目中,为了保证代码的严谨性,应该更多的使用严格相等。


表达式 case
在做比较之前,都会先计算每个 case 的值

  1. switch (true) {
  2. case num < 0:
  3. alert("Less than 0");
  4. break;
  5. case num >= 0 && num <= 10:
  6. alert("between 0 and 10");
  7. break;
  8. default:
  9. alert("More than 10");
  10. }

合并 case
通过在每个 case 后面都添加一个 break,就可以避免同时执行多个 case 代码,一般都会使用 break。

而在需要混合多种情况的时候,就可以省略 case 后面的 break,但是要记得添加注释,说明有意省略 break

  1. switch (i) {
  2. case 25:
  3. /* 合并两种情况 */
  4. case 35:
  5. alert("45");
  6. break;
  7. case 45:
  8. alert("45");
  9. break;
  10. default:
  11. alert("Other");
  12. }

需要注意的是

  • 合并的情况应该靠在一起,因为只能与相邻的 case 合并

  • 前面的情况没有任何语句,只有注释,而且应该有注释

  • 在合并的最后一种情况的语句结束后,都应该添加 break 关键字来跳出 switch

2. 循环语句

2.1 for

for 循环属于前测试循环结构,条件成立才会执行循环体内代码。

for 循环的语法组成:

  1. 定义初始值

  2. 设定循环成立的条件(条件成立循环继续,不成立循环结束)

  3. 条件成立会执行循环体中的内容

  4. 执行步长累加操作


遍历数组

  1. // webstrom 快捷键 itar[Tab],直接生成数组遍历
  2. // 正序遍历
  3. for ( var i = 0; i < arr.length; i++) {
  4. ...
  5. }
  6. // 倒序遍历
  7. for ( var i = arr.length - 1; i >= 0; i--) {
  8. ...
  9. }
  10. // 取奇数项
  11. for ( var i = 0; i < arr.length; i++) {
  12. // 索引为偶数,代表奇数项
  13. if (i % 2 === 0) {
  14. ...
  15. }
  16. }
  17. // 另一种更简单的方法:
  18. for ( var i = 0; i < arr.length; i += 2) {
  19. ...
  20. }

在 for 循环中出现的两个常用的关键字,也属于语句:

  • continue:结束本次循环,开始下一次循环

  • break:中断或者结束整个

  1. for (var i = 0; i < 10; i++) {
  2. if (i < 5) {
  3. i++;
  4. continue; //=> 结束本轮循环(后面的代码将不再执行),进行累加之后,继续执行下一轮循环
  5. }
  6. if (i > 7) {
  7. i += 2;
  8. break; //=> 强制结束整个循环,不执行后面代码,也不进行累加,开始3执行循环之后的代码
  9. }
  10. i += 1;
  11. }
  12. i //=> 10

2.2 while 和 do-while

while 语句属于前测试循环语句,只有前置条件成立之后,才会执行循环体内代码。也就是说,循环体可能永远不会被执行

do-while 语句属于后测试循环语句,是先执行循环体的代码,然后再判断条件是否成立。也就是说,循环体至少执行一次

  1. // 后测试循环
  2. do {
  3. statement
  4. } while (expression)
  5. // 前测试循环
  6. while (expression) {
  7. statement
  8. }

2.3 for-in

for-in 语句是一种精准的迭代语句,可以用来枚举对象的属性。

  1. for (var property in obj) {
  2. statement
  3. }

由于对象的属性没有顺序,因此,通过 for-in 循环中输出的属性名的顺序是不可预测的,返回的先后次序可能会因浏览器而异。

如果要迭代的对象的变量值是 null 或 undefined,for-in 语句在 ES5 之前会报错,ES5 之后更正了这一行为,不再报错,只是不执行循环体。为了保证最大限度的兼容性,建议在使用 for-in 循环之前,先检测确认该对象的值不是 null 或 undefined

2.4 label

使用 label 语句可以在代码中添加自定义标签,以便后面使用。

  1. label: statement;

注意,标签只能标记一条语句或者一个整块语句

加标签的语句一般都会与 for 语句等循环语句配合使用:

  1. start:
  2. for (var i=0; i < count; i++) {
  3. alert(i);
  4. }

添加的标签可以在将来由 break 或 continue 语句引用,从而返回代码中的特定位置

  1. var num = 0;
  2. outermost:
  3. for (var i=0; i < 10; i++) {
  4. for (var j=0; j < 10; i++) {
  5. if (i == 5 && j == 5) {
  6. break outermost;
  7. }
  8. num++;
  9. }
  10. }
  11. num; //=> 55

注意两者之间的区别

  1. var num = 0;
  2. outermost:
  3. for (var i=0; i < 10; i++) {
  4. for (var j=0; j < 10; i++) {
  5. if (i == 5 && j == 5) {
  6. continue outermost;
  7. }
  8. num++;
  9. }
  10. }
  11. num //=> 95