1. 条件判断语句

1.1 if-else

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

判断中,如果结果不是布尔值,那么会自动使用 Boolean 方法转换为布尔值
只有 0 / NaN / '' / null /undefinedfalse,其余为 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 语句在比较 expressionvalue 的值时使用的是全等操作符,所以不会发生类型转换

  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 循环中输出的属性名的顺序是不可预测的,返回的先后次序可能会因浏览器而异。

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

2.4 label

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

  1. label: statement;

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

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

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

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

  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