关于javascript:这两个函数之间的区别?(“function x” vs “var x = function”)

The difference between the two functions? (“function x” vs “var x = function”)

本问题已经有最佳答案,请猛点这里访问。

Possible Duplicate:
JavaScript: var functionName = function() {} vs function functionName() {}

有什么区别:

1
2
3
4
5
6
7
8
9
function sum(x, y) {
  return x+y;
}

// and

var sum = function (x, y) {
    return x+y;
}

为什么一个用在另一个上面?


第一个函数称为命名函数,第二个函数称为匿名函数。

关键的实际区别在于何时可以使用和函数。例如:

1
2
3
4
var z = sum(2, 3);
function sum(x, y) {
    return x+y;
}

z被分配为5,而:

1
2
3
4
var z = sum(2, 3);
var sum = function(x, y) {
    return x+y;
}

将失败,因为在执行第一行时,变量和尚未分配函数。

在执行开始之前,对命名函数进行解析并分配给它们的名称,这就是为什么命名函数可以在执行其定义的代码中进行utalissed。

按代码分配给函数的变量只能在执行过程超过分配之后,才能清楚地用作函数。


第一种倾向于用于以下几个原因:

  • 名称"sum"出现在进行调试的StackTrace在许多浏览器中更简单。
  • 名字"sum"可用于使之更容易的功能体用于递归函数。
  • 函数声明被"提升"在javascript中,所以在第一种情况下,功能保证为定义了一次。
  • 分号插入原因

    1
    2
    3
    var f = function (x) { return 4; }

    (f)

    把4赋给f

  • 不过,还有一些注意事项需要牢记。不做

    1
      var sum = function sum(x, y) { ... };

    在IE6上,因为它将导致创建两个函数对象。如果你这样做的话,尤其令人困惑

    1
      var sum = function mySym(x, y) { ... };

    根据标准,函数和(x,y)…}不能出现在if块或循环体中,因此不同的解释程序将处理

    1
    2
    3
    4
    5
    6
      if (0) {
        function foo() { return 1; }
      } else {
        function foo() { return 2; }
      }
      return foo();

    不同的。在这种情况下,你应该这样做

    1
    2
    3
    4
      var foo;
      if (0) {
        foo = function () { return 1; }
      } ...


    第一个是命名函数语句,第二个是为变量分配一个匿名函数表达式。

    函数语句将立即添加到其作用域中-在能够调用它之前,您不需要运行它,因此这是有效的:

    1
    2
    3
    4
    5
    var y = sum(1, 2);

    function sum(x, y) {
       return x + y;
    }

    但是函数表达式只在执行代码时分配给变量,因此这不起作用:

    1
    2
    3
    4
    5
    6
    // Error here because the function hasn't been assigned to sum yet.
    var y = sum(1, 2);

    var sum = function(x, y) {
       return x + y;
    }

    表达式表单的一个优点是,您可以使用它在不同的点为表达式分配不同的函数,这样您就可以更改函数,或者在不同的条件下使用不同的函数(例如,取决于所使用的浏览器)。

    命名函数语句的一个优点是,调试器将能够显示名称。但是,您可以命名函数表达式:

    1
    2
    3
    var sum = function sum(x, y) {
       return x + y;
    }

    但这可能会令人困惑,因为这两个名称实际上在不同的范围内,并且引用了不同的东西。


    您在那里发布的两个代码片段在几乎所有目的上都将以相同的方式运行。

    但是,行为上的区别在于,对于第二个变量,只能在代码中的该点之后调用该函数。

    对于第一个变量,函数可用于在上面声明函数的地方运行的代码。

    这是因为对于第二个变量,函数在运行时被分配给变量foo。首先,函数在解析时被分配给该标识符foo。

    更多技术信息

    javascript有三种定义函数的方法。

  • 第一个例子是函数声明。这将使用"function"语句创建一个函数。函数在解析时可用,可以在该范围内的任何地方调用。以后仍可以将其存储在变量或对象属性中。
  • 第二个代码段显示了一个函数表达式。这涉及到使用"函数"运算符来创建函数-该运算符的结果可以存储在任何变量或对象属性中。函数表达式就是这样强大的。函数表达式通常称为"匿名函数",因为它不必有名称,
  • 定义函数的第三种方法是"function()"构造函数,它在您的原始日志中没有显示。不建议使用它,因为它的工作方式与eval()相同,eval()存在问题。

  • 区别在于…

    这是一个无名函数

    1
    2
    3
    var sum = function (x, y) {
        return x+y;
    }

    所以,如果你发出警告(sum);你会得到"函数(x,y)返回x+y;"(无名称)虽然这是一个命名函数:

    1
    2
    3
    function sum(x, y) {
            return x+y;
    }

    如果你提醒(sum);现在你得到"函数和(x,y)返回x+y;"(名称是sum)

    如果使用探查器,命名函数会有所帮助,因为探查器可以告诉您函数sum的执行时间…etcetera而不是未知函数的执行时间…etcetera


    下面是另一个例子:函数sayhello(name)alert('hello'+name)

    现在,假设您想要修改按钮的onclick事件,比如它说"HelloWorld"。

    你不能写:

    yourbtn.onclik=sayhello("world"),因为必须提供函数引用。

    然后您可以使用第二种形式:yourbtn.onclick=function()sayHello('workd');

    附言:抱歉我的英语不好!


    他们的意思完全一样。只是句法上的糖分。后者更能揭示javascript的真正用途,即"sum"只是一个变量,用一个函数对象初始化,然后可以用其他东西替换:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    $ js
    js> function sum(x,y) { return x+y; }
    js> sum(1,2);
    3
    js> sum=3
    3
    js> sum(1,2);
    typein:4: TypeError: sum is not a function
    js> sum
    3