函数声明不应放在块中.使用函数表达式或将语句移动到外部函数的顶部

Jam*_*ber 16 javascript jslint jshint

我有以下代码:

if (typeof console === "object" && typeof console.error === "function") {
    function e(msg) {"use strict"; console.info(msg);}
}
Run Code Online (Sandbox Code Playgroud)

jsLint为其提供以下错误:

函数语句不应放在块中.使用函数表达式或将语句移动到外部函数的顶部.

为什么会出现此错误,这是什么意思?

Kyl*_*Mit 48

说明

在jsLintErrors页面中有关警告的功能语句不应放在块中:

引发此错误以突出显示可能无法按预期工作的代码.在大多数环境中,您的代码将运行时没有错误,但可能不是您期望的方式.在某些环境中,它可能会导致致命的语法错误.

那是因为Function声明被提升到它们出现的范围的顶部.

因此,不可能通过块语句有条件地声明函数.

让我们通过一个简单的例子探讨这个问题引发的问题:

if (true) {
    function example() {
        console.log('hello');
    }
}
Run Code Online (Sandbox Code Playgroud)

最好的情况是您的代码令人困惑.在上面的例子中,它看起来像你想要做的只是申报访问功能是什么,如果条件为真.但是,当函数被提升到作用域的顶部时,它实际上将被解释为:

function example() {
    console.log('hello');
}
if (true) {}
Run Code Online (Sandbox Code Playgroud)

这很危险,因为它看起来不像你原来的代码所期望的那样.条件块实际上是空的(并且是不必要的),并且每个人都可以访问该函数,无论条件是否为true或false.

最糟糕的情况是浏览器不了解如何处理嵌套函数,并在尝试使用它时抛出语法错误.这取决于运行JavaScript的引擎.看起来Firefox就是这样一个引擎.如果在Firefox中运行以下代码,则在执行以下代码时将抛出错误:

if (true) {
    example();
    function example() {
        console.log('hello');
    }
}
Run Code Online (Sandbox Code Playgroud)

如果打开控制台,您应该看到以下错误:

ReferenceError:未定义示例

那你怎么解决这个问题呢?

使用函数赋值而不是函数声明

这是一个快速细分:

// Declaration
function declarationFunction() {}

// Assignment
var assignmentFunction = function() {}
Run Code Online (Sandbox Code Playgroud)

功能分配没有提升到范围的顶部.
函数声明被提升到范围的顶部.

所以要有条件地设置示例函数,只需在块中分配它,如下所示:

var example;
if (true) {
    example = function() {
        console.log('hello');
    }
}
Run Code Online (Sandbox Code Playgroud)


Tom*_*rda 11

如果阻止你不应该在里面创建函数.你做得好多了:

var e = function(){};

if(typeof console === "object" && typeof console.error === "function"){
    e = function (msg){ ... };
}
Run Code Online (Sandbox Code Playgroud)