## 1、三元运算符

``````function handleEvent(event) {
if (currentState === STATE_INITIAL) {
// do something
} else if (currentState === STATE_SECONDARY) {
// do something
} else if (currentState === STATE_FINAL) {
// do something
}
}``````

``````function handleEvent(event) {
currentState === STATE_INITIAL ?
// do something :
currentState === STATE_SECONDARY ?
// do something :
// do something
}``````

## 2、耍点小聪明

### 2.1 短路求值（Short-circuit Evaluation）

``````let x = 10;
let result;
if (x > 5) {
result = "x is greater than 5";
} else {
result = "x is less than or equal to 5";
}

// 利用 && 运算符
let x = 10;
let result = x > 5 && "x is greater than 5" || "x is less than or equal to 5";``````

### 2.2 字符串拼接

``````function setAccType(accType) {
if (accType == "PLATINUM") {
return "Platinum Customer";
} else if (accType == "GOLD") {
return "Gold Customer";
} else if (accType == "SILVER") {
return "Silver Customer";
}
}``````

``````function setAccType(accType){
return accType[0] + accType.slice(1).toLowerCase() + ' Customer';
// or
return `\${accType[0] + accType.slice(1).toLowerCase()} Customer`;
}``````

## 3、switch/case

`switch/case` 语句也是比较常用的技巧，来看下面这个例子：

``````if (status === 200) {
handleSuccess()
} else if (status === 401) {
handleUnauthorized()
} else if (status === 404) {
handleNotFound()
} else {
handleUnknownError()
}``````

``````switch (status) {
case 200:
handleSuccess()
break
case 401:
handleUnauthorized()
break
case 404:
handleNotFound()
break
default:
handleUnknownError()
break
}``````

## 4、数组的 includes 方法

``````function getIngredients(foodType) {
let ingredients = [];

if (foodType === 'pizza') {
ingredients = ['cheese', 'sauce', 'pepperoni'];
} else if (foodType === 'burger') {
ingredients = ['bun', 'beef patty', 'lettuce', 'tomato', 'onion'];
} else if (foodType === 'taco') {
ingredients = ['tortilla', 'beef', 'lettuce', 'shredded cheese'];
} else if (foodType === 'sandwich') {
ingredients = ['bread', 'turkey', 'lettuce', 'mayo'];
} else {
console.log('Unknown food type');
}

return ingredients;
}``````

``````function getIngredients(foodType) {
{food: 'pizza', ingredients: ['cheese', 'sauce', 'pepperoni']},
{food: 'burger', ingredients: ['bun', 'beef patty', 'lettuce', 'tomato', 'onion']},
{food: 'taco', ingredients: ['tortilla', 'beef', 'lettuce', 'shredded cheese']},
{food: 'sandwich', ingredients: ['bread', 'turkey', 'lettuce', 'mayo']}
];

if (item === undefined) {
console.log('Unknown food type');
return [];
}

return item.ingredients;
}``````

1. 可读性更强：使用数组和对象结合来代替`if..else`语句，代码更加简洁易懂，并且减少了嵌套，更容易阅读和理解。
2. 扩展性更好：添加新的菜单项只需要向`menu`数组中添加一个新的对象即可，而不需要修改原函数`getIngredients`，大大提高了代码的扩展性。
3. 可维护性更好：当想要删除或更新某个菜单项时，只需要修改`menu`数组即可，而不需要修改原函数`getIngredients`。因此，代码的可维护性也更好。

## 5、使用对象或者Map

### 5.1 对象

``````function getStatusColor (status) {
if (status === 'success') {
return 'green'
}

if (status === 'warning') {
return 'yellow'
}

if (status === 'info') {
return 'blue'
}

if (status === 'error') {
return 'red'
}
}``````
``````const statusColors = {
success: 'green',
warning: 'yellow',
info: 'blue',
error: 'red'
};

function getStatusColor(status) {
return statusColors[status] || '';
}``````

1. 可读性更好：当需要增加新的状态时，只需要添加一个新的键值对即可。这比原来的`if..else`语句更易于阅读和维护。
2. 执行效率更高：因为在JavaScript中，对象的属性访问是常数时间，而`if..else`语句则需要逐个匹配条件。由于我们只需要访问一个属性，所以使用对象映射比`if..else`语句更有效率。

### 5.2 Map

``````function test(color) {
switch (color) {
case 'red':
return ['apple', 'strawberry'];
case 'yellow':
return ['banana', 'pineapple'];
case 'purple':
return ['grape', 'plum'];
default:
return [];
}
}

test(null); // []
test('yellow'); // ['banana', 'pineapple']``````

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

function test(color) {
return foodMap.get(color) || [];
}``````

1. 这段代码更加简洁：使用`Map`数据结构可以使代码更短，可读性也更强。
2. 可维护性更高：将数据存储在`Map`中，如果需要修改或添加一个颜色和对应的食物列表，只需在`Map`中修改或添加一条记录即可。
3. 搜索时间更短：由于`Map`内部使用了哈希表来存储键值对，所以搜索时间可能比基于条件语句的方法更快。当有大量数据时，这种优化可能会显著提高代码的性能。

## 6、减少嵌套，提前返回

### 6.1 场景1

``````function getLifeStage(age) {
let stage;

if (age < 1) {
stage = 'baby';
} else {
if (age < 4) {
stage = 'toddler';
} else {
if (age < 13) {
stage = 'child';
} else {
if (age < 20) {
stage = 'teenager';
} else {
if (age < 65) {
} else {
stage = 'senior';
}
}
}
}
}

return `Your life stage is \${stage}`;
}``````

``````function getLifeStage(age) {
if (age < 1) {
return 'Your life stage is baby';
}

if (age < 4) {
return 'Your life stage is toddler';
}

if (age < 13) {
return 'Your life stage is child';
}

if (age < 20) {
return 'Your life stage is teenager';
}

if (age < 65) {
}

return 'Your life stage is senior';
}``````

1. 可读性更强：减少了嵌套层次以及大括号，使代码更加简洁明了，并且易于阅读和理解。
2. 扩展性更好：当需要添加或删除一个年龄段时，只需要在相应的位置插入或删除一个if语句即可，而不需要影响其他部分的代码，大大提高了代码的扩展性。
3. 错误处理更好：每个if语句可以处理一种情况，这样可以更及时地返回正确的结果。同时，避免了多个判断条件匹配的情况下重复执行同一个代码块的情况。

### 6.2 场景2

``````function test(fruit, quantity) {
const redFruits = ['apple', 'strawberry', 'cherry', 'cranberries'];

// 条件1: fruit 必须非空
if (fruit) {
// 条件2: 必须是红色的水果
if (redFruits.includes(fruit)) {
console.log('red');

// 条件3: 必须大于10个
if (quantity > 10) {
console.log('big quantity');
}
}
} else {
throw new Error('No fruit!');
}
}

test(null); // error: No fruits
test('apple'); // red
test('apple', 20); // red, big quantity``````

• 1个if/else语句，过滤掉无效的条件
• 3层嵌套的if语句（条件1、2和3）。

``````function test(fruit, quantity) {
const redFruits = ['apple', 'strawberry', 'cherry', 'cranberries'];

// 先判断小概率情况，提前返回
if (!fruit) throw new Error('No fruit!');

if (redFruits.includes(fruit)) {
console.log('red');

if (quantity > 10) {
console.log('big quantity');
}
}
}``````

``````function test(fruit, quantity) {
const redFruits = ['apple', 'strawberry', 'cherry', 'cranberries'];

if (!fruit) throw new Error('No fruit!');
if (!redFruits.includes(fruit)) return;

console.log('red');

if (quantity > 10) {
console.log('big quantity');
}
}``````

## 7、隐藏高阶技能：find(Boolean)

``````function ComponentByType({ type }) {
if (type === "type_1") {
return (
<>
{/* 其他很复杂的组件 */}
<Component1 />
{/* 其他很复杂的组件 */}
</>
);
}

if (type === "type_2") {
return (
<>
{/* 其他很复杂的组件 */}
<Component2 />
{/* 其他很复杂的组件 */}
</>
);
}

if (type === "type_3") {
return (
<>
{/* 其他很复杂的组件 */}
<Component3 />
{/* 其他很复杂的组件 */}
</>
);
}

if (type === "type_4") {
return (
<>
{/* 其他很复杂的组件 */}
<Component4 />
{/* 其他很复杂的组件 */}
</>
);
}
}``````

``````function ComponentByType({ type }) {
return (
<>
{/* 其他很复杂的组件 */}
<>
{
[
type === "type_1" && <Component1 />,
type === "type_2" && <Component2 />,
type === "type_3" && <Component3 />,
type === "type_4" && <Component4 />
].find(Boolean)
}
</>
{/* 其他很复杂的组件 */}
</>
);
}``````

`find(Boolean)`可以实现条件判断，因为在JavaScript中，布尔值的true和false可以被转换为数字1和0。在这个例子里，当某个条件不满足时，对应的React组件（例如`<Component1 />`）会被解析为布尔值false并存储在数组中，相反当条件满足时，对应的React组件会被解析为一个真值true。这样，使用`find(Boolean)`就可以找到第一个真值（即第一个满足条件的React组件），并把它渲染到页面上。

``````[
type === "type_1" && <Component1 />,
type === "type_2" && <Component2 />,
type === "type_3" && <Component3 />,
type === "type_4" && <Component4 />
].find(Boolean) || <DefaultComponent />``````

`find(Boolean)`的作用是查找数组中第一个布尔值为`true`的元素，并返回该元素的值。数组中包含多个条件语句以及相应的React组件，当某个条件满足时，对应的组件会被返回并渲染到页面上；否则会返回`false`，由于我们使用了条件运算符`&&`，所以这个返回值会被自动忽略。

``[0,false,null,1,2].find(Boolean) // 返回 1``

• `0` 被转换为 `false`
• `false` 本身就是布尔值 `false`
• `null` 被转换为 `false`
• `1` 被转换为 `true`
• `2` 被转换为 `true`

``````[0,false,null,1,2].map(Boolean); // [false, false, false, true, true]

[0,false,null,1,2].find(Boolean); // 1``````

## 8、责任链模式

``````function placeOrder(order) {
if (!order.items || !Array.isArray(order.items) || order.items.length === 0) {
console.log("At least one item should be specified to place an order.");
return;
}

// 校验商品库存是否充足
for (let i = 0; i < order.items.length; i++) {
let item = order.items[i];
if (!checkStock(item.productId, item.quantity)) {
console.log(`Product \${item.productId} is out of stock.`);
return;
}
}

return;
}

// 扣减库存
for (let i = 0; i < order.items.length; i++) {
let item = order.items[i];
decreaseStock(item.productId, item.quantity);
}

// 生成订单
let orderId = generateOrderId();
console.log(`Order \${orderId} placed successfully.`);
}``````

``````class OrderValidator {
constructor() {
this.nextHandler = null;
}
setNext(handler) {
this.nextHandler = handler;
return handler;
}
handle(order) {}
}

class ItemValidator extends OrderValidator {
handle(order) {
if (!order.items || !Array.isArray(order.items) || order.items.length === 0) {
console.log("At least one item should be specified to place an order.");
return false;
} else {
return this.nextHandler.handle(order);
}
}
}

class StockValidator extends OrderValidator {
handle(order) {
for (let i = 0; i < order.items.length; i++) {
let item = order.items[i];
if (!checkStock(item.productId, item.quantity)) {
console.log(`Product \${item.productId} is out of stock.`);
return false;
}
}
return this.nextHandler.handle(order);
}
}

handle(order) {
return false;
} else {
return this.nextHandler.handle(order);
}
}
}

class StockDeductor extends OrderValidator {
handle(order) {
for (let i = 0; i < order.items.length; i++) {
let item = order.items[i];
decreaseStock(item.productId, item.quantity);
}
return this.nextHandler.handle(order);
}
}

class OrderGenerator extends OrderValidator {
handle(order) {
let orderId = generateOrderId();
console.log(`Order \${orderId} placed successfully.`);
return true;
}
}

let itemValidator = new ItemValidator();
let stockValidator = new StockValidator();
let stockDeductor = new StockDeductor();
let orderGenerator = new OrderGenerator();

function placeOrder(order) {
itemValidator.handle(order);
}``````

1. 代码更加灵活和易于扩展：在需要添加或修改处理步骤时，只需要新增或修改相应的处理器类即可，不需要修改原有的代码。
2. 代码复用性更高：不同的处理器类可以被复用，具有更好的可读性和可维护性。
3. 代码结构更加清晰和易于理解：使用责任链模式将系统分解成多个小而简单的部分，每一个部分都有自己的处理逻辑和职责。这样的代码结构更加清晰和易于理解。