if-else 语句优化

多条件判断嵌套

单一 if 语句使用 && / || 进行连接

if (.. && .. && .. && .. )

缺点是会有非常长条件判断块,并且要考虑每个条件中运算符的优先级

通常会写成多重 if-else 语句嵌套

  1. if ( a === true) {
  2. if ( b === true) {
  3. if ( c === true) {
  4. // ...
  5. } else {
  6. // ...
  7. }
  8. } else {
  9. // ...
  10. }
  11. } else {
  12. // ...
  13. }

可读性差

卫语句

do…while(false) 把多重嵌套的 if 写成顺序的 if

  1. do {
  2. if (a === false) {
  3. // ...
  4. break;
  5. }
  6. if (b === false) {
  7. // ...
  8. break;
  9. if (c === false) {
  10. // ...
  11. break;
  12. }
  13. // ...
  14. } while (false);

if…else 并列判断

  1. function formatDay(strDay) {
  2. if(strDay === 'Mon') return 'Monday';
  3. else if(strDay === 'Tue') return 'Tuesday';
  4. else if(strDay === 'Web') return 'Wednesday';
  5. else if(strDay === 'Thu') return 'Thursday';
  6. else if(strDay === 'Fri') return 'Friday';
  7. else if(strDay === 'Sat') return 'Saturday';
  8. else if(strDay === 'Sun') return 'Sunday';
  9. else return 'Unknow';
  10. }
  11. function calc(command, num1, num2) {
  12. if(command === 'add') return num1 + num2;
  13. else if(command === 'sub') return num1 - num2;
  14. else if(command === 'mul') return num1 * num2;
  15. else if(command === 'div') return num1 / num2;
  16. else return 0;
  17. }

条件越来越多,可读性变得差

表驱动

  1. const mapDayFormat = {
  2. 'Mon': 'Monday',
  3. 'Tue': 'Tuesday',
  4. 'Wed': 'Wednesday',
  5. 'Thu': 'Thursday',
  6. 'Fri': 'Friday',
  7. 'Sat': 'Saturday',
  8. 'Sun': 'Sunday',
  9. 'Other' : 'Unknow',
  10. }
  11. function formatDay(strDay) {
  12. if(!mapDayFormat[strDay]) strDay = 'Other';
  13. return mapDayFormat[strDay];
  14. }
  15. const mapCalculate = {
  16. add(num1, num2) {
  17. return num1 + num2;
  18. },
  19. sub(num1, num2) {
  20. return num1 - num2;
  21. },
  22. mul(num1, num2) {
  23. return num1 * num2;
  24. },
  25. div(num1, num2) {
  26. return num1 / num2;
  27. },
  28. other() {
  29. return 0;
  30. }
  31. }
  32. function calc(command, num1, num2) {
  33. if(!mapCalculate[command]) command = 'other';
  34. return mapCalculate[command](num1, num2);
  35. }

随着指令的增多,表也会变得冗长,可读性也会下降。表会把指令和对应的方法存放在一起,对其新增/修改指令会出现一些麻烦。

策略模式

  1. class Calculator {
  2. constructor() {
  3. this.strategy = null;
  4. }
  5. setStrategy(strategy) {
  6. this.strategy = strategy;
  7. }
  8. calculateResult(num1, num2) {
  9. return this.strategy.execute(num1, num2);
  10. }
  11. }
  12. class Add {
  13. execute(num1, num2) {
  14. return num1 + num2;
  15. }
  16. }
  17. class Sub {
  18. execute(num1, num2) {
  19. return num1 - num2;
  20. }
  21. }
  22. class Mul {
  23. execute(num1, num2) {
  24. return num1 * num2;
  25. }
  26. }
  27. class Div {
  28. execute(num1, num2) {
  29. return num1 / num2;
  30. }
  31. }
  32. const calc = new Calculator();
  33. calc.setStrategy(new Add());
  34. console.log(calc.calculateResult(1,2));
  35. calc.setStrategy(new Sub());
  36. console.log(calc.calculateResult(9,5));

条件合并,函数提炼

  1. function getuserInfoContent(userInfo) {
  2. if (userInfo.name == '') {
  3. return 'Invalid data received';
  4. }
  5. if (userInfo.id <= 0) {
  6. return 'Invalid data received';
  7. }
  8. if (userInfo.status == '') {
  9. return 'Invalid data received';
  10. }
  11. if (!userInfo.isActivated) {
  12. return 'User status is not normal';
  13. }
  14. if (userInfo.status != 'valid') {
  15. return 'User status is not normal';
  16. }
  17. return 'Welcome' + userInfo.name;
  18. }
  19. // 条件合并,函数提炼
  20. function getUserInfoContent(userInfo) {
  21. if(!isDataValid(userInfo)) {
  22. return 'Invalid data received';
  23. }
  24. if(!isUserStatusNormal(userInfo)) {
  25. return 'User status is not normal';
  26. }
  27. return 'Welcome' + userInfo.name;
  28. }
  29. function isDataValid(userInfo) {
  30. if(userInfo.name == '' || userInfo.id <= 0 || useriNfo.status == '') {
  31. return false;
  32. }
  33. return true;
  34. }
  35. function isUserStatusNormal(userInfo) {
  36. if(!userInfo.isActivated || userInfo.status != 'valid') {
  37. return false;
  38. }
  39. return true;
  40. }

函数优化

函数多参数

  1. function multipleParams(isNew, aParam, bParam, cParam, dParam) {
  2. if(isNew) {
  3. console.log(aParam, bParam, cParam, dParam);
  4. } else {
  5. console.log(aParam, bParam, cParam);
  6. }
  7. }
  8. const a = 1,
  9. b = 'a',
  10. c = false,
  11. d = 2.3,
  12. isNewVersion = true;
  13. multipleParams(isNewVersion, a, b, c, d);

多个参数可能出传参时顺序写反的问题
使用对象进行优化

  1. function multipleParams(params) {
  2. const {isNew, aParam, bParam, cParam, dParam} = params;
  3. if(isNew) {
  4. console.log(aParam, bParam, cParam, dParam);
  5. } else {
  6. console.log(aParam, bParam, cParam);
  7. }
  8. }
  9. multipleParams({
  10. isNew: false,
  11. a: 1,
  12. b: 'b',
  13. c: true,
  14. d: 3.2
  15. })

复用函数提炼:相同逻辑提取

函数命名艺术

  1. 函数命名不应过于追求简短,而是尽可能清晰表达出函数的作用
  2. 高质量的函数命名是可以让函数体本身或是被调用出无需任何注释
  3. 函数命名应该偏重于函数的功能而非执行的过程

    冗长函数分解原则:单一职责

    每当感觉以什么来注释什么东西的时候,就应该把说明的东西写进一个独立的函数当中,并以其用途进行命名。