提高 JavaScript 可读性的 10 个技巧


每日分享前端插件干货,欢迎关注!

 

1.日志级别和语义方法

console.log("hello world")
console.warn("this is a warning")
console.error("this is an error")
console.info("this is info")
console.debug("this is debug")
console.trace("show trace")

如果你尝试console.warn,那么你会得到trace调试信息,这意味着更容易调试代码。

让我们再试试其他的控制台功能吧:)

原代码:

console.log("Error: API key should not be empty")

改进后的代码:

console.error("Error: API key should not be empty")

2. 避免对布尔变量使用否定意义的名称

老实说,双重否定理解起来更费劲。

例如:isStarted vs. isNotStarted

原代码:

const isInvalidApiKey = apiKey === null

if (isInvalidApiKey) {}

改进后的代码:

const isValidApiKey = apiKey != null

if (!isValidApiKey) {}

3. 避免使用标记位参数

不知道函数使用的标记参数是什么?那么你最好先阅读函数声明。

原代码:

renderResult(true)

function renderResult(isAuthenticated) {
    if (isAuthenticated) {
       return <p>App</p>
    } else {
        return <p>Please login</p>
    }

}

使用对象参数:

renderResult({isAuthenticated: true})

function renderResult({isAuthenticated}) {
    if (isAuthenticated) {
        return <p>App</p>
    } else {
        return <p>Please login</p>
    }

}

使用2个函数:

function renderAuthenticatedApp() {
    return <p>App</p>
}

function renderUnAuthenticatedApp() {
    return <p>Please login</p>
}

isAuthenticated ? renderAuthenticatedApp() : renderUnAuthenticatedApp()

4. 使用卫语句

首先说一下“卫语句”是什么东西?

卫语句就是把复杂的条件表达式拆分成多个条件表达式,比如一个很复杂的表达式,嵌套了好几层的if-else语句,将其转换为多个if语句,实现它的逻辑,这多条的if语句就是卫语句。

例如,原代码即将形成了一个嵌套地狱:

if (statusCode === 200) {
    // success
} else {
    if (statusCode === 500) {
        // Internal Server Error
    } else if (statusCode === 400) {
        // Not Found
    } else {
        // Other error
    }
}

使用卫语句改进后:

if (statusCode === 500) {
    // Internal Server Error
}

if (statusCode === 400) {
    // Not Found
}

if (statusCode !== 200) {
    // Other error
}

// success

5. 让代码一目了然

🐨简单易懂

🐨可重复使用

🐨长的描述性变量名称胜过冗长的注释

例如:

// verify that user has added a credit card
function verify(user) {}

改进后

function verifyThatUserHasAddedCreditCard(user) {}

再看一个例子:

if (country !== 'finland' &&
    country !== 'germany' &&
    country !== 'vietnam' &&
    country !== 'russia' &&
    type !== '💣'
) {
    return Promise.reject('Not available')
}

改进后

const isInAvailableCountries = (
    country === 'finland' ||
    country === 'germany' ||
    country === 'vietnam' ||
    country === 'russia'
)

const hasBoom = type === '💣'

if (!isInAvailableCountries || hasBoom) {
    return Promise.reject('Not available')
}

创建更合适的条件判断

const availableCountries = ['finland', 'germany', 'vietnam', 'russia']
const isInAvailableCountries = availableCountries.includes(country)

const hasBoom = type === '💣'

if (!isInAvailableCountries || hasBoom) {
    return Promise.reject('Not available')
}

6. 不可能的状态就让它不可能

🐨易于理解

🐨预防出现大量bug

🐨停止使用类似于isLoading的布尔值

例如:

isLoading: true
isError: false

isLoading: false
isError: true

// imposible states
isLoading: true
isError: true

改进后:

const LOADING_STATE = 'LOADING_STATE'
const ERROR_STATE = 'ERROR_STATE'

const state = LOADING_STATE

再看一个例子:

const [isLoading, setIsLoading] = React.useState(false)
const [error, setError] = React.useState(null)
const [coffee, setCoffee] = React.useState(null)

function handleButtonClick() {
    setIsLoading(true)
    setError(null)
    setCoffee(null)

    getCoffee('cappuccino', 'small', 'finland', true).then(coffee => {
        setIsLoading(false)
        setError(null)
        setCoffee(coffee)
    }).catch(error => {
        setIsLoading(false)
        setError(error)
    })
}

改进后:

const state = {
    idle: 'idle',
    loading: 'loading',
    error: 'error',
    success: 'success',
}

const [error, setError] = React.useState(null)
const [coffee, setCoffee] = React.useState(null)
const [status, setStatus] = React.useState(state.idle) 

function handleButtonClick() {
    setStatus(state.loading)

    getCoffee('cappuccino', 'small', 'finland', true).then(coffee => {
        setStatus(state.success)
        setCoffee(coffee)
    }).catch(error => {
        setStatus(state.error)
        setError(error)
    })
}

7.参数个数太多,可以用对象代替

🐨参数顺序无关紧要

🐨方便传递可选参数

例如:

function getBox(type, size, price, color) {}

getBox('carry', undefined, 10, 'red')

改进后:

function getBox(options) {
    const {type, size, price, color} = options
}

getBox({
    type: 'carry',
    price: 10,
    color: 'red'
})

8. 使用Object.assign赋默认值

例如:

function getBox(options) {

    options.type = options.type || 'carry'
    options.size = options.size || 'small'
    options.price = options.price || 10
    options.color = options.color || 'red'

    const {type, size, price, color} = options
}

改进后:

function getBox(customOptions) {

    const defaults = {
        type: 'carry',
        size: 'small',
        price: 10,
        color: 'red',
    }

    const options = Object.assign(defaults, customOptions)

    const {type, size, price, color} = options
}

原代码:

export function getCoffee(type, size, country, hasIce) {

    type = type || 'cappuccino'
    size = size || 'small'
    country = country || 'finland'
    hasIce = hasIce || false
}

可以用以下3个方法改进:

function getCoffee(customOptions) {
    const defaultOptions = {
        type: 'cappuccino',
        size: 'small',
        country: 'finland',
        hasIce: false
    }

    const options = Object.assign(defaultOptions, customOptions)
}

function getCoffee(options = {}) {
    const {
        type = 'cappuccino',
        size = 'small',
        country = 'finland',
        hasIce = false
    } = options
}

function getCoffee({
    type = 'cappuccino', 
    size = 'small',
    country = 'finland',
    hasIce = false
} = {}) {
}

9. 用对象字面量替换switch语句

老实说,我也喜欢switch,但我其实并不知道什么时候使用switch语句和对象字面量。我依靠直觉来判断该选哪一个。

例如:

let drink
switch(type) {
    case 'cappuccino':
        drink = 'Cappuccino';
        break;
    case 'flatWhite':
        drink = 'Flat White';
        break;
    case 'espresso':
        drink = 'Espresso';
        break;
    default:
        drink = 'Unknown drink';
}

可以改进为:

const menu = {
    'cappuccino': 'Cappuccino',
    'flatWhite': 'Flat White',
    'espresso': 'Espresso',
    'default': 'Unknown drink'
}

const drink = menu[type] || menu['default']

避免不合理的抽象

我不知道如何创建好的抽象,但我知道我创建了很多坏的抽象。

凡是皆有两面性。为了减少代码重复,我们牺牲了改变需求的能力。这不是一笔好的交易。——Dan Abramov

下面的代码用于获取订单,且我使用了Redux进行状态管理。这就是样板!!!如果我们在匆忙之下创建了这样的抽象:

获取订单

// Action Type
const FETCH_ORDERS_START = "FETCH_ORDERS_START";
const FETCH_ORDERS_SUCCESS = "FETCH_ORDERS_SUCCESS";
const FETCH_ORDERS_FAILED = "FETCH_ORDERS_FAILED"
// Action
export const fetchOrder = (token) => {
    return dispatch => {
        dispatch(fetchOrdersStart);
        axios.get('/orders.json?auth=' + token).then(res => {
            dispatch(fetchOrdersSuccess(res));
        }).catch(err => {
            dispatch(fetchOrdersFailed(err));
        });
    };

}

export const fetchOrdersSuccess = (orders) => {
    return {
        type: FETCH_ORDERS_SUCCESS,
        orders: orders,
    };
};

export const fetchOrdersFailed = (error) => {
    return {
        type: FETCH_ORDERS_FAILED,
        error: error,
    };
};

export const fetchOrdersStart = () => {
    return {
        type: FETCH_ORDERS_START,
    };
};

我敢打赌你必须得阅读完所有的代码才能理解该抽象。所以应该这样改进:

// Action
const moduleName = 'order'
const path = '/order'

const {moduleActionTypes, moduleActions} = useModuleActions(moduleName, path)

function fetchOrder() {
    moduleActionTypes.getModel()    
}

function updateOrder(data) {
    moduleActionTypes.updateModel(data)
}

感谢阅读!如果你觉得文章写的对你有帮助的话,也欢迎分享给你的朋友!

 

 

每日分享前端插件干货,欢迎关注!

  • 12
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

珍儿2022

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值