1, 使用 Array.includes 处理多种条件
让我们来看一下的例子:
- // conditionfunction test(fruit) {
- if (fruit == 'apple' || fruit == 'strawberry') {
- console.log('red');
- }
- }
一眼看去, 以上的例子貌似没有什么问题. 但是, 如果我们加入更多的红色水果, 比如车厘子 (cherry) 和蔓越橘(cranberries)? 那就要使用 || 写更多的条件判断了.
为了解决以上问题, 我们可以使用 Array.includes 来重写以上的条件判断. 看以下例子:
- function test(fruit) {
- // extract conditions to array
- const redFruits = ['apple', 'strawberry', 'cherry', 'cranberries'];
- if (redFruits.includes(fruit)) {
- console.log('red');
- }
- }
将这些 "红色水果"(条件)提取到数组里面, 这样写就会看起来很简洁了.
2, 减少嵌套, 尽早 return
下面我们增加两个条件判断来扩展下上一个例子:
如果没有水果则抛出异常
如果数量超出 10 则输出水果数量
- function test(fruit, quantity) {
- const redFruits = ['apple', 'strawberry', 'cherry', 'cranberries'];
- // condition 1: fruit must has value
- if (fruit) {
- // condition 2: must be red
- if (redFruits.includes(fruit)) {
- console.log('red');
- // condition 3: must be big quantity
- if (quantity > 10) {
- console.log('big quantity');
- }
- }
- } else {
- throw new Error('No fruit!');
- }
- }
- // test results
- test(null); // error: No fruits
- test('apple'); // print: red
- test('apple', 20); // print: red, big quantity
看着以上的代码, 发现以下的问题:
一个过滤无效条件的 if/else 语句
嵌套三级 if 条件语句
我个人遵循的一般规则: 在处理无效条件时尽早 return
- /_ return early when invalid conditions found _/
- function test(fruit, quantity) {
- const redFruits = ['apple', 'strawberry', 'cherry', 'cranberries'];
- // condition 1: throw error early
- if (!fruit) throw new Error('No fruit!');
- // condition 2: must be red
- if (redFruits.includes(fruit)) {
- console.log('red');
- // condition 3: must be big quantity
- if (quantity > 10) {
- console.log('big quantity');
- }
- }
- }
通过这种写法, 可以减少一层嵌套. 当 if 语句很长的时候, 这种写法就比较好.(试想一下, 你需要滚动到很底部才能看到 else 语言, 这样不酷).
我们也可以用相反的条件判断和尽早返回来减少 if 语句嵌套, 看以下第二个条件是如何处理的.
- /_ return early when invalid conditions found _/
- function test(fruit, quantity) {
- const redFruits = ['apple', 'strawberry', 'cherry', 'cranberries'];
- if (!fruit) throw new Error('No fruit!'); // condition 1: throw error early
- if (!redFruits.includes(fruit)) return; // condition 2: stop when fruit is not red
- console.log('red');
- // condition 3: must be big quantity
- if (quantity > 10) {
- console.log('big quantity');
- }
- }
通过在第二个条件里取反的条件来判断, 现在的代码释放了一个嵌套. 当我们要写很长的逻辑以及想停止更一步的过程时, 这种方法很凑效.
但是, 这样写并不是硬性的, 要看具体的场景. 有时候, 你要问下自己, 这样的写法 (没有嵌套) 是否比之前那种 (在条件 2 嵌套) 更好或者更具可读性.
对我来说, 我只会远离之前的那种写法(在条件 2 嵌套), 注意有以下两个原因:
对比嵌套 if 语句, 这种写法更短, 更简洁
取反的条件判断可能招致更多的思考过程(增加认知负荷)
- function test(fruit, quantity) {
- if (!fruit) return;
- const q = quantity || 1; // if quantity not provided, default to one
- console.log(`We have ${q} ${fruit}!`);
- }
- //test results
- test('banana'); // We have 1 banana!
- test('apple', 2); // We have 2 apple!
- function test(fruit, quantity = 1) {
- // if quantity not provided, default to one
- if (!fruit) return;
- console.log(`We have ${quantity} ${fruit}!`);
- }
- //test results
- test('banana'); // We have 1 banana!
- test('apple', 2); // We have 2 apple!
- function test(fruit) {
- // printing fruit name if value provided
- if (fruit && fruit.name) {
- console.log (fruit.name);
- } else {
- console.log('unknown');
- }
- }
- //test results
- test(undefined); // unknown
- test({
- }); // unknown
- test({
- name: 'apple', color: 'red'
- }); // apple
- // destructing - get name property only
- // assign default empty object {
- }
- function test({
- name
- } = {
- }) {
- console.log (name || 'unknown');
- }
- //test results
- test(undefined); // unknown
- test({
- }); // unknown
- test({
- name: 'apple', color: 'red'
- }); // apple
- // Include lodash library, you will get _
- function test(fruit) {
- console.log(__.get(fruit, 'name', 'unknown'); // get property name, if not available, assign default value 'unknown'
- }
- //test results
- test(undefined); // unknown
- test({
- }); // unknown
- test({
- name: 'apple', color: 'red'
- }); // apple
- function test(color) {
- // use switch case to find fruits in color
- switch (color) {
- case 'red':
- return ['apple', 'strawberry'];
- case 'yellow':
- return ['banana', 'pineapple'];
- case 'purple':
- return ['grape', 'plum'];
- default:
- return [];
- }
- }
- //test results
- test(null); // []
- test('yellow'); // ['banana', 'pineapple']
- // use object literal to find fruits in color
- const fruitColor = {
- red: ['apple', 'strawberry'],
- yellow: ['banana', 'pineapple'],
- purple: ['grape', 'plum']
- };
- function test(color) {
- return fruitColor[color] || [];
- }
- // use Map to find fruits in color
- const fruitColor = new Map()
- .set('red', ['apple', 'strawberry'])
- .set('yellow', ['banana', 'pineapple'])
- .set('purple', ['grape', 'plum']);
- function test(color) {
- return fruitColor.get(color) || [];
- }
- const fruits = [
- {
- name: 'apple', color: 'red'
- },
- {
- name: 'banana', color: 'yellow'
- },
- {
- name: 'grape', color: 'purple'
- }
- ];
- function test() {
- let isAllRed = true;
- // condition: all fruits must be red
- for (let f of fruits) {
- if (!isAllRed) break;
- isAllRed = (f.color == 'red');
- }
- console.log(isAllRed); // false
- }
- const fruits = [
- {
- name: 'apple', color: 'red'
- },
- {
- name: 'banana', color: 'yellow'
- },
- {
- name: 'grape', color: 'purple'
- }
- ];
- function test() {
- // condition: short way, all fruits must be red
- const isAllRed = fruits.every(f => f.color == 'red');
- console.log(isAllRed); // false
- }
- const fruits = [
- {
- name: 'apple', color: 'red'
- },
- {
- name: 'banana', color: 'yellow'
- },
- {
- name: 'grape', color: 'purple'
- }
- ];function test() {
- // condition: if any fruit is red
来源: http://blog.51cto.com/13982920/2310156