Coding Tip: Try to Code Without If-statements
现在开始,请尝试尽量避免使用if
语句来实现我们的业务
你可能会疑问不使用if
有什么好处?额~,可能也没啥很明显的好处,就是换种思考方式来解决问题。if-else
并没有错,但在某些情况下大量的if-else
可能会降低代码可读性。下面会列举一些实例带你感受其中的奥妙。
Challenge #1: 统计数值数组中共有多少个奇数
已知一个整数类型数组,统计该数组中奇数的个数
const arrayOfIntegers = [1, 4, 5, 9, 0, -1, 5];
if实现
let counter = 0;
arrayOfIntegers.forEach((integer) => {
const remainder = Math.abs(integer % 2);
if (remainder === 1) {
counter++;
}
});
console.log(counter);
非if实现
let counter = 0;
arrayOfIntegers.forEach((integer) => {
const remainder = Math.abs(integer % 2);
// 偶数除2的余数为零,奇数的余数为一
counter += remainder;
});
console.log(counter);
记: 上述两个例子,forEach是会改变原数组的,方法是可变的
,违背了当下所提倡的函数式编程immutable
理念,不用在意,不是本文关注点。两个例子比较而言,if语句
的实现可能更具兼容性,可以适应于数组元素是小数
的情况。若数组元素为浮点类型,第二个例子就无法正常使用。
Challenge #2: 判断一个日期是周末还是工作日
实现一个函数,日期对象 new Date()
作为输入,根据不同日期返回当天是工作日
还是周末
。
if实现
const weekendOrWeekday = inputDate => {
const day = inputDate.getDay();
if (day === 0 || day === 6) {
return 'weekend';
}
return 'weekday';
// Or, for ternary fans:
// return (day === 0 || day === 6) ? 'weekend' : 'weekday';
};
console.log(weekendOrWeekday(new Date()));
非if实现
const weekendOrWeekday = (inputDate) => {
const day = inputDate.getDay();
return weekendOrWeekday.labels[day] ||
weekendOrWeekday.labels['default'];
};
weekendOrWeekday.labels = {
0: 'weekend',
6: 'weekend',
default: 'weekday'
};
console.log(weekendOrWeekday(new Date()));
有没有注意到,if语句
中的数字代表哪天是周末,判定条件分布的较为零散,我们需要做的是将数字和周末或工作日
类型对应起来,如例子2,可以使用一个对象或者map来存储对应关系。
上述两个例子对比,可以明显看出非if代码
实现具有更好的可读性和扩展性
Challenge #3: The doubler function (here be dragons),翻译不出来~尬~
实现一个doubler函数,根据输入不同,做如下处理:
- 若输入是
number
类型, 做翻倍处理(5 => 10, -10 => -20) - 若输入是
string
类型,重复每个字符('hello' => 'hheelloo') - 若输入是
function
类型,调用执行两次函数 - 若输入是
array
类型,对数组的每个元素做doubler
处理 - 若输入是
object
类型,对对象的每个属性做doubler
处理
switch
实现
const doubler = (input) => {
switch (typeof input) {
case 'number':
return input + input;
case 'string':
return input
.split('')
.map(letter => letter + letter)
.join('');
case 'object':
Object.keys(input)
.map(key => (input[key] = doubler(input[key])));
return input;
case 'function':
input();
input();
}
};
console.log(doubler(-10));
console.log(doubler('hey'));
console.log(doubler([5, 'hello']));
console.log(doubler({ a: 5, b: 'hello' }));
console.log(
doubler(function() {
console.log('call-me');
}),
);
非switch
实现
const doubler = (input) => {
return doubler.operationsByType[typeof input](input);
};
doubler.operationsByType = {
number: (input) => input + input,
string: (input) =>
input
.split('')
.map((letter) => letter + letter)
.join(''),
function: (input) => {
input();
input();
},
object: (input) => {
Object.keys(input)
.map((key) => (input[key] = doubler(input[key])));
return input;
},
};
console.log(doubler(-10));
console.log(doubler('hey'));
console.log(doubler([5, 'hello']));
console.log(doubler({ a: 5, b: 'hello' }));
console.log(
doubler(function() {
console.log('call-me');
}),
);
和Challenge #2类似,将条件值聚合在一起做统一处理。
总结
当if-else
的判断条件较多时,将条件做集中处理(用object存储其对应关系--条件做key,处理做value)。好处是增删某个条件变得容易,代码更加可读,提倡使用key-value
对应来取代一部分的if-else
的条件判断。
【开发环境推荐】 Cloud Studio 是基于浏览器的集成式开发环境,支持绝大部分编程语言,包括 HTML5、PHP、Python、Java、Ruby、C/C++、.NET 小程序等等,无需下载安装程序,一键切换开发环境。 Cloud Studio提供了完整的 Linux 环境,并且支持自定义域名指向,动态计算资源调整,可以完成各种应用的开发编译与部署。