赞
踩
相信大家听说过回调地狱——回调函数层层嵌套,极大降低代码可读性。其实,if-else
层层嵌套,如下图所示,也会形成类似回调地狱的情况。
当业务比较复杂,判断条件比较多,项目进度比较赶时,特别容易使用过多if-else
。其弊端挺多的,如代码可读性差、代码混乱、复杂度高、影响开发效率、维护成本高等。
因此,我们在日常编码时,有必要采取一些措施避免这些问题。本文的初衷不是建议大家完全不用if-else
,而是希望我们能够在学会更多解决方案后更优雅地编码。
if-else
的优化/替代方案逻辑非(logic NOT),是逻辑运算中的一种,就是指本来值的反值。
当你想这么写时……
- 1、判断是否为空
- if(value === null || value === NaN || value === 0 || value === ''|| value === undefined )
- {
- ……
- }
-
- 2、判断是否数组是否含有符合某条件的元素
- const name = arr.find(item => item.status === 'error')?.name;
- if(name !== undefined && name !== ''){
- ……
- }
-
不妨尝试这么写:
- 1、判断是否为空
- if(!value){……}
-
- 2、判断是否数组是否含有符合某条件的元素
- if(!!arr.find(item => item.status === 'error')?.name){……}
-
三元运算符: condition ? exprIfTrue : exprIfFalse; 如果条件为真值,则执行冒号(:)前的表达式;若条件为假值,则执行最后的表达式。
当你想这么写时……
- let beverage = '';
- if(age > 20){
- beverage = 'beer';
- } else {
- beverage = 'juice';
- }
-
不妨尝试这么写:
- const beverage = age > 20 ? 'beer' : 'juice';
-
tips: 建议只用一层三元运算符,多层嵌套可读性差。
&&
为取假运算,从左到右依次判断,如果遇到一个假值,就返回假值,以后不再执行,否则返回最后一个真值;
||
为取真运算,从左到右依次判断,如果遇到一个真值,就返回真值,以后不再执行,否则返回最后一个假值。
当你想这么写时……
- if (isOnline){
- makeReservation(user);
- }
-
不妨尝试这么写:
- isOnline && makeReservation(user);
-
当你想这么写时……
- let result;
- if (type === 'add'){
- result = a + b;
- } else if(type === 'subtract'){
- result = a - b;
- } else if(type === 'multiply'){
- result = a * b;
- } else if(type === 'divide'){
- result = a / b;
- } else {
- console.log('Calculation is not recognized');
- }
-
不妨尝试这么写:
- let result;
- switch (type) {
- case 'add':
- result = a + b;
- break;
- case 'subtract':
- result = a - b;
- break;
- case 'multiply':
- result = a * b;
- break;
- case 'divide':
- result = a / b;
- break;
- default:
- console.log('Calculation is not recognized');
- }
-

个人认为,对于这类比较简单的判断,用switch语句虽然不会减少代码量,但是会更清晰喔。
当你想这么写时……
- function itemDropped(item, location) {
- if (!item) {
- return false;
- } else if (outOfBounds(location) {
- var error = outOfBounds;
- server.notify(item, error);
- items.resetAll();
- return false;
- } else {
- animateCanvas();
- server.notify(item, location);
- return true;
- }
- }
-
不妨尝试这么写:
- function itemDropped(item, location) {
- const dropOut = function () {
- server.notify(item, outOfBounds);
- items.resetAll();
- return false;
- };
-
- const dropIn = function () {
- animateCanvas();
- server.notify(item, location);
- return true;
- };
-
- return !!item && (outOfBounds(location) ? dropOut() : dropIn());
- }
-

细心的朋友会发现,在这个例子中,同时使用了前文提及的优化方案。这说明我们在编码时可以根据实际情况混合使用多种解决方案。
① 定义普通对象
对于方案3的例子,不妨尝试这么写:
- function calculate(action, num1, num2) {
- const actions = {
- add: (a, b) => a + b,
- subtract: (a, b) => a - b,
- multiply: (a, b) => a * b,
- divide: (a, b) => a / b,
- };
-
- return actions[action]?.(num1, num2) ?? "Calculation is not recognized";
- }
-
② 定义 Map 对象
普通对象的键需要是字符串,而 Map[6] 对象的键可以是一个对象、数组或者更多类型,更加灵活。
- let statusMap = new Map([
- [
- { role: "打工人", status: "1" },
- () => { },
- ],
- [
- { role: "打工人", status: "2" },
- () => { },
- ],
- [
- { role: "老板娘", status: "1" },
- () => { },
- ],
- ]);
-
- let getStatus = function (role, status) {
- statusMap.forEach((value, key) => {
- if (JSON.stringify(key) === JSON.stringify({ role, status })) {
- value();
- }
- });
- };
-
- getStatus("打工人", "1");
-

tips: JSON.stringify()[7]可用于深比较/深拷贝。
责任链模式:将整个处理的逻辑改写成一条责任传递链,请求在这条链上传递,直到有一个对象处理这个请求。
例如 JS 中的_事件冒泡_。
简单来说,_事件冒泡_就是在一个对象上绑定事件,如果定义了事件的处理程序,就会调用处理程序。相反没有定义的话,这个事件会向对象的父级传播,直到事件被执行,最后到达最外层,document对象上。
这意味着,在这种模式下,总会有程序处理该事件。
再举个
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。