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

时间:2015-01-24 11:55:43

标签: javascript function syntax

我对我的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(){}之间究竟有什么区别?

2 个答案:

答案 0 :(得分:7)

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

引用MDN documentation on var

  

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

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

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

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

  6.         

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

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

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

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

您将获得相同的ReferenceError: f is not defined

答案 1 :(得分:2)

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

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