【问题标题】:Function declarations should not be placed in blocks. Use a function expression or move the statement to the top of the outer function函数声明不应放在块中。使用函数表达式或将语句移动到外部函数的顶部
【发布时间】:2013-01-03 19:48:21
【问题描述】:

我有以下代码:

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

jsLint 给出以下错误:

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

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

【问题讨论】:

  • 信息很清楚。它建议您将函数移出 if 块,这是有道理的。
  • 没有说如果阻止它!不知道block 是什么

标签: javascript jslint jshint


【解决方案1】:

你不应该在 if 块中创建函数。你最好这样做:

var e = function(){};

if(typeof console === "object" && typeof console.error === "function"){
    e = function (msg){ ... };
}

【讨论】:

    【解决方案2】:

    说明

    来自关于警告 Function statements should not be placed in blocks 的 jsLintErrors 页面:

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

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

    因此,不可能有条件地用块语句声明一个函数。

    示例

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

    if (true) {
        function example() {
            console.log('hello');
        }
    }
    

    最好的情况是您的代码令人困惑。在上面的例子中,看起来你想做的只是声明对函数的访问 if 条件为真。然而,当函数被提升到作用域的顶部时,它实际上会被这样解释:

    function example() {
        console.log('hello');
    }
    if (true) {}
    

    这很危险,因为它看起来不像您根据原始代码所期望的那样。条件块实际上是空的(并且是不必要的),并且每个人都可以访问该函数,无论条件的计算结果是真还是假。

    最坏的情况是浏览器不明白如何处理嵌套函数,并在尝试使用它时抛出语法错误。这取决于运行 JavaScript 的引擎。 Firefox 似乎就是这样一种引擎。如果在Firefox中运行以下代码,执行以下代码时会报错:

    if (true) {
        example();
        function example() {
            console.log('hello');
        }
    }

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

    解决方案

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

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

    这里有一个快速细分:

    // Declaration
    function declarationFunction() {}
    
    // Assignment
    var assignmentFunction = function() {}
    

    函数分配没有提升到作用域的顶部。
    函数声明被提升到作用域的顶部。

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

    var example;
    if (true) {
        example = function() {
            console.log('hello');
        }
    }
    

    【讨论】:

    • @staypuftman 当然有它的怪癖!在 Chrome 中,您还必须考虑严格/非严格模式。如果'use strict',则声明不会提升到 if 块之外,在非严格模式下。所以最安全的选择是使用关于这个的 lint 建议
    猜你喜欢
    • 2019-05-08
    • 2011-06-06
    • 1970-01-01
    • 1970-01-01
    • 2014-01-30
    • 2019-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多