【问题标题】:Functions may be declared only at top level in strict mode在严格模式下,函数只能在顶层声明
【发布时间】:2016-01-26 09:13:12
【问题描述】:

在严格模式下使用 FireFox 时出现此错误。但我不确定这意味着什么。我认为这意味着必须在调用该函数之前声明该函数,但错误仍然存​​在。

SyntaxError:在严格模式代码中,函数只能在顶层或直接在另一个函数中声明

这是导致错误的代码的 sn-p:

var process = new function(){

  var self = this;

  self.test = function(value,callback){
    var startTime = Date.now();

     function update(){     //<--- error is here
                value++;
                startTime        = Date.now();

                if(value < 100){ 
                    setTimeout(update, 0);
                }
                callback(value);
    }       
    update();
  }

};

所以我想知道如何使用 strict 正确地写出这段 sn-p 代码?顶级是什么意思?这是否意味着全局定义而不是在函数中本地定义?

另外,我有use strict,为什么Chrome不会出现这个问题?

【问题讨论】:

  • 错误是SyntaxError: in strict mode code, functions may be declared only at top level or immediately within another function
  • value++startTime = Date.now();?
  • 哎呀,格式化问题时必须删除它
  • 那个sn-p的代码不会导致任何错误。您能否发布一个演示您遇到的问题的最小代码示例
  • @JaromandaX 可能是因为您没有在 Firefox 中打开严格模式。

标签: javascript


【解决方案1】:

您必须在严格模式下将本地函数放在父函数中的其他代码之前:

var process = function () {
    var self = this;
    self.test = function (value, callback) {

        function update() {
            value++;
            startTime = Date.now();
            if (value < 100) {
                setTimeout(update, 0);
            }
            callback(value);
        }

        var startTime = Date.now();
        update();
    }
};

本文对此进行了描述:

New ES5 strict mode requirement: function statements not at top level of a program or function are prohibited

MDN Strict Mode

不过,在我自己的测试中(与我读过的文章相反),我发现 Chrome 和 Firefox 的当前版本只有在本地函数定义位于块内时才会抱怨它(例如在 if 内)或for 语句或类似块。

我想我需要去找一个实际的规范来看看它是怎么说的。

【讨论】:

  • 鉴于我在 Chrome 中没有遇到此问题,这是否表明 use strict 在 Chrome 中实际上不起作用?
  • @Dave - 当前版本的 Chrome 和 Firefox 似乎只在函数位于块内(如在 if 语句内)时才会抱怨这个问题,尽管这不是描述该功能的方式在我读过的资料中。
  • 嗯,Chrome 还没有给我任何投诉。但 Firefox 讨厌一切,哈哈。似乎 Chrome 没有那么严格 =/
  • 嗯,我不相信这个答案在规范方面是正确的。警告中的“立即”应该是指嵌套,而不是顺序。如果更改这些语句的顺序确实解决了错误,那听起来像是 Firefox 中的错误。另外,请注意 ES5 和 ES6 语法在此错误方面有所不同。该错误适用于 ES5,我认为它不适用于 ES6。
  • @JMM - 很明显,浏览器和严格模式已经改变了他们的想法。如果您查看第二个代码示例here,MDN 清楚地指出,由于嵌套函数声明在严格模式下是不允许的,因此应该导致语法错误,但所有当前的浏览器都允许这样做。事情似乎有点混乱。这就是我在 2015 年写下这个答案的信息。
【解决方案2】:

Internet Explorer 错误明确指出函数名称不能在函数内“声明”。所以使用自调用函数表达式对我有用。

此代码失败:

    c.prototype.isitReal=function(t){
    var matched = false;
    this.each(function(item){
        // declaring a new function within a function fails 
        function getChildren(el){
            ....
            getChildren(el[a].children);
            ....
        }
        getChildren(el.children); // invoke function
    });
    return matched;
};

此代码有效:

    c.prototype.isitReal=function(t){
    var matched = false;
    this.each(function(item){
        // convert the function to an expression of a function
        // by wraping the entire function in ( )

        (function getChildren(el){
            ....
            getChildren(el[a].children);
            ....
            // then invoke the function expresion by adding ()
            // to the end. Pass in any arguments here also
        })(el.children,arg2,arg3);
    });
    return matched;
};

在 FF 76、MSIE 10、Chrome Canary 81 中测试

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-08-25
    • 1970-01-01
    • 2017-07-03
    • 2013-10-24
    • 2019-06-13
    • 2015-10-29
    • 1970-01-01
    相关资源
    最近更新 更多