六种颇有用的编程技巧,帮助你成为更好的 JavaScript 程序员

1. 常量提取和Array.includes运用

// bad example

function printAnimals(animal) {
    if (animal === 'dog' || animal === 'cat') {
        console.log(`I have a ${animal}`);
    }
}

console.log(printAnimals('dog')); // I have a dog
复制代码

上面的代码看起来不错,由于咱们只有两个动物要检查。可是,咱们不肯定用户输入。若是咱们还有其余动物怎么办?若是咱们继续用更多的OR语句来扩展该语句,则代码将变得更难维护,而不是那么干净。javascript

解:java

咱们可使用重写上面的条件 Array.includes数组

// good example

function printAnimals(animal) {
    const animals = ['dog', 'cat', 'hamster', 'turtle']; 
    
    if (animals.includes(animal)) {
        console.log(`I have a ${animal}`);
    }
}

console.log(printAnimals('hamster')); // I have a hamster
复制代码

2. 尽快return

// bad example

const printAnimalDetails = animal => {
    let result;

    // condition 1: check if animal has a value
    if (animal) {

        // condition 2: check if animal has a type property
        if (animal.type) {

            // condition 3: check if animal has a name property
            if (animal.name) {

                // condition 4: check if animal has a gender property
                if (animal.gender) {
                    result = `${animal.name} is a ${animal.gender} ${animal.type};`;
                } else {
                    result = "No animal gender";
                }
            } else {
                result = "No animal name";
            }
        } else {
            result = "No animal type";
        }
    } else {
        result = "No animal";
    }

    return result;
};

console.log(printAnimalDetails()); // 'No animal'

console.log(printAnimalDetails({ type: "dog", gender: "female" })); // 'No animal name'

console.log(printAnimalDetails({ type: "dog", name: "Lucy" })); // 'No animal gender'

console.log(printAnimalDetails({ type: "dog", name: "Lucy", gender: "female" })); // 'Lucy is a female dog'
复制代码

它工做正常,可是代码又长又难以维护。维护代码的时候可能会浪费一些时间弄清楚右括号在哪里。bash

想象一下,若是代码具备更复杂的逻辑,将会发生什么 —— 不少 if .. elseapp

咱们可使用三元运算符&&条件等来重构上述函数,但让咱们使用多个return语句编写更精确的代码。函数

// good example

const printAnimalDetails = ({ type, name, gender } = {}) => {
    if (!type) return 'No animal type';
    if (!name) return 'No animal name';
    if (!gender) return 'No animal gender';

    return `${name} is a ${gender} ${type}`;
}

console.log(printAnimalDetails()); // 'No animal type'

console.log(printAnimalDetails({ type: dog })); // 'No animal name'

console.log(printAnimalDetails({ type: dog, gender: female })); // 'No animal name'

console.log(printAnimalDetails({ type: dog, name: 'Lucy', gender: 'female' })); // 'Lucy is a female dog'
复制代码

另外一个例子:学习

// bad example

function printVegetablesWithQuantity(vegetable, quantity) {
    const vegetables = ['potato', 'cabbage', 'cauliflower', 'asparagus'];

    // condition 1: vegetable should be present
    if (vegetable) {
        // condition 2: must be one of the item from the list
        if (vegetables.includes(vegetable)) {
            console.log(`I like ${vegetable}`);

            // condition 3: must be large quantity
            if (quantity >= 10) {
                console.log('I have bought a large quantity');
            }
        }
    } else {
        throw new Error('No vegetable from the list!');
    }
}

printVegetablesWithQuantity(null); //  No vegetable from the list!
printVegetablesWithQuantity('cabbage'); // I like cabbage
printVegetablesWithQuantity('cabbage', 20);
// I like cabbage
// I have bought a large quantity
复制代码

上面例子有如下问题测试

  • 第一层if用于过滤无效条件
  • 3层嵌套的if语句

解:ui

发现无效条件时尽快返回spa

// good

function printVegetablesWithQuantity(vegetable, quantity) {

    const vegetables = ['potato', 'cabbage', 'cauliflower', 'asparagus'];

    // condition 1: throw error early
    if (!vegetable) throw new Error('No vegetable from the list!');

    // condition 2: must be in the list
    if (vegetables.includes(vegetable)) {
        console.log(`I like ${vegetable}`);

        // condition 3: must be a large quantity
        if (quantity >= 10) {
            console.log('I have bought a large quantity');
        }
    }
}
复制代码

3. 使用对象

// bad example

function printFruits(color) {
    // use switch case to find fruits by color
    switch (color) {
        case 'red':
            return ['apple', 'strawberry'];
        case 'yellow':
            return ['banana', 'pineapple'];
        case 'purple':
            return ['grape', 'plum'];
        default:
            return [];
    }
}

printFruits(null); // []
printFruits('yellow'); // ['banana', 'pineapple']
复制代码

上面的代码没有错,可是仍然很冗长。

使用object映射更简洁的语法能够实现相同的结果:

// good example

const fruitColor = {
    red: ['apple', 'strawberry'],
    yellow: ['banana', 'pineapple'],
    purple: ['grape', 'plum']
};

function printFruits(color) {
    return fruitColor[color] || [];
}

// 或者使用 Map,Map 是自 ES2015 起可用的对象类型

const fruitColor = new Map()
    .set('red', ['apple', 'strawberry'])
    .set('yellow', ['banana', 'pineapple'])
    .set('purple', ['grape', 'plum']);

function printFruits(color) {
    return fruitColor.get(color) || [];
}

// 或者使用 Array.filter,同样能够实现

const fruits = [
    { name: 'apple', color: 'red' },
    { name: 'strawberry', color: 'red' },
    { name: 'banana', color: 'yellow' },
    { name: 'pineapple', color: 'yellow' },
    { name: 'grape', color: 'purple' },
    { name: 'plum', color: 'purple' }
];

function printFruits(color) {
    return fruits.filter(fruit => fruit.color === color);
}
复制代码

4. 默认参数和解构

使用JavaScript时,咱们老是须要检查 null / undefined 值并赋值,不然编译会中断。

// bad example

function printVegetableName(vegetable) {
    if (vegetable && vegetable.name) {
        console.log(vegetable.name);
    } else {
        console.log('unknown');
    }
}

printVegetableName(undefined); // unknown
printVegetableName({}); // unknown
printVegetableName({ name: 'cabbage', quantity: 2 }); // cabbage
复制代码

解:

经过使用默认参数和结构来避免烦人的判断条件

// good example

function printVegetableName({ name } = {}) {
    console.log(name || 'unknown');
}

printVegetableName(undefined); // unknown
printVegetableName({}); // unknown
printVegetableName({ name: 'cabbage', quantity: 2 }); // cabbage
复制代码

5. 使用Array.everyArray.some等新语法糖

// bad example

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
}
复制代码

代码太长了!咱们能够减小行数,使用Array.every

// good example

const fruits = [
    { name: 'apple', color: 'red' },
    { name: 'banana', color: 'yellow' },
    { name: 'grape', color: 'purple' }
];

function test() {
    const isAllRed = fruits.every(f => f.color == 'red');
    console.log(isAllRed); // 全是红色:false
}

// 以相似的方式,若是咱们要测试是否有红色的水果,咱们可使用 Array.some 在一行中实现它。

const fruits = [
    { name: 'apple', color: 'red' },
    { name: 'banana', color: 'yellow' },
    { name: 'grape', color: 'purple' }
];

function test() {
    const isAllRed = fruits.some(f => f.color == 'red');
    console.log(isAnyRed); // 包含红色:true
}
复制代码

更多数组语法可查看 MDN Javascript Array Docs,不一一展开。

6. ??

彩蛋

看看下面代码,你必定有过这样的烦恼,特别是接口过来鬼知道怎样的数据

const car = {
    model: 'Fiesta',
    manufacturer: {
        name: 'Ford',
        address: {
            street: 'Some Street Name',
            number: '5555',
            state: 'USA'
        }
    }
}

const model = car && car.model || 'default model';

const street = car && car.manufacturer && car.manufacturer.address && car.manufacturer.address.street || 'default street';

const phoneNumber = car && car.manufacturer && car.manufacturer.address && car.manufacturer.phoneNumber;

console.log(model) // 'Fiesta'
console.log(street) // 'Some Street Name'
console.log(phoneNumber) // undefined

const isManufacturerFromUSA = () => {
    if (car && car.manufacturer && car.manufacturer.address && car.manufacturer.address.state === 'USA') {
        console.log('true');
    }
}

const isManufacturerFromUSA = () => {
    if (car && car.manufacturer && car.manufacturer.address && car.manufacturer.address.state === 'USA') {
        console.log('true');
    }
}

checkCarManufacturerState() // 'true'
复制代码

您能够清楚地看到,在对象结构复杂且不受控的状况下,这会变得多么混乱。

有一些第三方库,例如lodash或idx具备本身的功能。例如lodash有_.get方法。

可是,JavaScript语言自己引入的此功能很是酷。

这些新功能的工做方式以下:

const model = car ?.model ?? 'default model';

const street = car ?.manufacturer ?.address ?.street ?? 'default street';

const isManufacturerFromUSA = () => {
    if (car ?.manufacturer ?.address ?.state === 'USA') {
        console.log('true');
    }
}
复制代码

这看起来更漂亮,更易于维护。它已经在 TC39 stage 3 规范定制中。

很快就能用上这爽到飞起的写法了!

结语

让咱们学习并尝试新的技巧和技术,编写更干净,更可维护的代码。

材料

Tips to write better Conditionals in JavaScript

相关文章
相关标签/搜索