全局范围中的函数表达式与函数声明之间的区别

kra*_*r65 1 javascript syntax function

我对我的js感到困惑.通常我定义这样的函数:

function f(){
    // do stuff
}
Run Code Online (Sandbox Code Playgroud)

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

f = function(){
    // do stuff
}
Run Code Online (Sandbox Code Playgroud)

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

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);
    });
}
Run Code Online (Sandbox Code Playgroud)

但是当我定义f如下:

function f(){
    alert('IT WORKS!!');
}
Run Code Online (Sandbox Code Playgroud)

然后我点击该行,它给出了一个ReferenceError: f is not defined.

所以我想知道:function f(){}和之间的区别是f = function(){}什么?

the*_*eye 7

在不使用var语句的情况下定义函数时,默认情况下,该函数将被定义为全局范围中的属性.

引用MDN文档var,

在执行赋值时,为未声明的变量赋值会隐式地将其创建为全局变量(它将成为全局对象的属性).声明和未声明变量之间的差异是:

  1. 声明的变量在声明它们的执行上下文中受到约束.未声明的变量总是全局的.

  2. 声明变量是在执行任何代码之前创建的.在执行分配给它们的代码之前,不存在未声明的变量.

  3. 声明的变量是其执行上下文(函数或全局)的不可配置属性.未声明的变量是可配置的(例如可以删除).

由于这三个差异,未能声明变量很可能会导致意外结果.因此,建议始终声明变量,无论它们是在函数还是全局范围内.在ECMAScript 5严格模式下,分配给未声明的变量会引发错误.

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

由于第二个函数定义是在全局作用域tr的onclick中可以找到的f.尝试使用这样的var语句

var f = function(){
    alert('IT WORKS!!');
}
Run Code Online (Sandbox Code Playgroud)

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