全局作用域中的函数表达式与函数声明的区别

Difference between function expression in global scope and function declaration

我对我的 js 中的某些东西感到困惑。通常我这样定义函数:

function f(){
    // do stuff
}

但我也可以这样定义函数:

f = function(){
    // do stuff
}

我一直认为它们之间没有区别,但我现在发现这是可行的:

f = function(){
    alert('IT WORKS!!');
}

function createCallback(request){
    request.done(function(data){
        var html = '';
        data['result'].forEach(function(bill){
            html += "<tr onclick=\"f();\"><td>" + bill.title + "</td></tr>";
        });
        $("#someId").html(html);
    });
}

但是当我如下定义f时:

function f(){
    alert('IT WORKS!!');
}

然后我单击该行,它给出了 ReferenceError: f is not defined

所以我想知道:function f(){}f = function(){} 之间到底有什么区别?

当你定义一个函数而不使用var语句时,默认情况下该函数将在全局范围内被定义为一个属性。

引用 MDN documentation on var,

Assigning a value to an undeclared variable implicitly creates it as a global variable (it becomes a property of the global object) when the assignment is executed. The differences between declared and undeclared variables are:

  1. Declared variables are constrained in the execution context in which they are declared. Undeclared variables are always global.

  2. Declared variables are created before any code is executed. Undeclared variables do not exist until the code assigning to them is executed.

  3. Declared variables are a non-configurable property of their execution context (function or global). Undeclared variables are configurable (e.g. can be deleted).

Because of these three differences, failure to declare variables will very likely lead to unexpected results. Thus it is recommended to always declare variables, regardless of whether they are in a function or global scope. And in ECMAScript 5 strict mode, assigning to an undeclared variable throws an error.

因此,当您使用 function function_name(...){...} 语法定义时,它将在当前范围内。

由于第二个函数定义在全局范围tr的onclick可以找到f。尝试使用 var 这样的语句

var f = function(){
    alert('IT WORKS!!');
}

你会得到相同的 ReferenceError: f is not defined

您忘记了 var 语句。使用 f = function(){ } 时,该函数是全局定义的。这就是为什么它可以从 onclick 处理程序访问而另一个不能访问的原因。

另请阅读@Nehal 建议的 var functionName = function() {} vs function functionName() {}