cssmagic / blog

CSS魔法 - 博客
http://blog.cssmagic.net/
2.81k stars 274 forks source link

如何改善既有 JS 代码:修复常见的 ESLint 报警(三) #91

Open cssmagic opened 6 years ago

cssmagic commented 6 years ago

前言

ESLint 是目前最主流、最强大的 JS 代码校验工具。当我们的代码触发了 ESLint 的报警规则时,ESLint 就会提示错误。

本系列文章将详细讲解那些需要手工介入修复的 ESLint 规则,帮助你顺利地把既有代码迁移到 ESLint 的保护之中。

no-empty

禁止出现空代码块,比如 if/else/for/catch 等代码块都在报警之列。

比如下面这个判断语句,if 块就是空的:

if (foo) {

} else {
    bar()
}

我们把判断条件反转一下,就可以消灭掉空的 if 块了。代码还更简练些:

if (!foo) {
    bar()
}

在某些情况下,判断条件反转之后并不易读,则可以添加注释来打破 “空代码块” 的状态:

if (foo) {
    // do nothing
} else {
    bar()
}

你可能意识到了:代块码中只有注释存在,就不算是 “空” 的。因为这条规则的用意还是希望你把代码意图表达清楚,既然你在空代码块中写注释了,那说明你已经在解释这个空代码块存在的意义,ESLint 就没有必要报警了。

try/catch 来说也是一样。代码中的 “静默失败” 通常会写成这样(这里 catch 块是空的):

try {
    bar()
} catch (e) {}

代码行为本身并没有什么问题,但读代码的人并不一定知道你的意图是静默失败,他可能会误以为这段代码没写完。所以你需要显式地说明你的意图。同样,加个注释就行:

try {
    bar()
} catch (e) {
    // 静默失败
}

no-empty-function

禁止出现空函数。

代码中为什么会出现空函数?很可能是没写完,你只声明了这个函数,但还没来得及实现。如果是这种情况,直接补完就好了。

还有另一种情况,你确实需要一个啥也不做的函数,类似于 jQuery / Underscore / LoDash 中的 .noop()。出现这个需求的场景可能是这样的:某个函数接受一个回调函数作为参数,你往往会准备一个空函数作为参数的默认值。

此时,空函数的存在是合理的。那么问题来了,如何抑制这条规则的报警?

我真的需要一个空函数

如果你的项目本身就依赖上面提到的类库,那不如直接使用它们提供的 .noop() 函数。

如果需要自己写,则可以通过注释来表明意图:

function noop() {
    // do nothing
}

这样就可以规避 “空” 函数的存在。

空函数作为参数默认值

如果你有兴趣的话,还可以进入实际的代码之中,看看案发现场有没有什么线索。我们来看个例子。

假设你有一个函数,其功能是通过 Ajax 获取数据并展示出来。你为这个函数设计了一个参数,接受回调函数,以便在加载完成之后做点事情:

function showData(dataUrl, callback) {
    // 准备一个空函数作为默认值
    function noop() {}
    callback = callback || noop

    // 获取数据
    getData(dataUrl)
        .then(function (data) {
            // 渲染数据并展示出来
            var html = render(data)
            wrapper.innerHTML = html
            // 好,正事儿做完,这里可以调用回调函数了
            callback()
        })
}

好,我们还原一下代码的初衷——我们为 callback 参数准备默认值 noop,是为了在最后一行语句 callback() 可以正常执行;否则当 callback 参数没传的时候,最后一行会抛错。

但实际上,如果 callback 参数传进来的不是一个函数,最后一行同样会抛错!所以我们应该先判一下传进来的 callback 是不是函数,再调用它。而此时,callback 参数有没有默认值就不那么重要了。比如整段代码可以改成这样:

function showData(dataUrl, callback) {
    getData(dataUrl)
        .then(function (data) {
            var html = render(data)
            wrapper.innerHTML = html
            // 先判一下回调函数是否合法,再调用它
            // 当然,你需要准备好一个 isFunction() 工具函数
            if (isFunction(callback)) callback()
        })
}

这样一来,代码更严谨了,而且也不需要用到空函数。

(待续……)


本文在 “CSS魔法” 微信公众号首发,扫码立即订阅:

weixin-qrcode


© Creative Commons BY-NC-ND 4.0   |   我要订阅   |   我要打赏