声明变量中的JavaScript函数?

时间:2011-11-13 07:02:15

标签: javascript function

我正在阅读本教程:http://nathansjslessons.appspot.com/

里面有一个课程说:

// A simple function that adds one
var plusOne = function (x) {
    return x + 1;
};

我习惯看到这样的功能:

function myFunction() {
    return x + 1;
};

第一个和第二个之间有什么区别?

4 个答案:

答案 0 :(得分:2)

阅读@ post撰写的CMS。他在解释 FunctionDeclaration FunctionExpression 之间的区别方面做得非常出色。引用他所写的内容:

  

可以用不同的方式声明函数,compare the following

     

1-使用分配给变量的<{3}}构造函数定义的函数乘以

  var multiply = new Function("x", "y", "return x * y;");
     

2-名为 multiply 的函数的函数声明:

  function multiply(x, y) {
     return x * y;
  }
     

3-分配给变量乘法的函数表达式

  var multiply = function (x, y) {
     return x * y;
  };
     

4-命名函数表达式 func_name ,分配给变量乘法

  var multiply = function func_name(x, y) {
     return x * y;
  };

简单来说,以下代码可以是 FunctionDeclaration FunctionExpression ,具体取决于具体情况:

function foo() {}

以上是 FunctionDeclaration

0, function foo() {}

以上是 FunctionExpression 。 @CMS在上述答案中详细解释了两者之间的差异。

参考你的问题:

// A simple function that adds one
var plusOne = function (x) {   // a function expression is assigned to a variable
    return x + 1;
};

function myFunction() {        // a simple function declaration
    return x + 1;
};

答案 1 :(得分:1)

最后。 2.只是声明上的差异。

答案 2 :(得分:1)

他们几乎做同样的事情,但两者兼而有之。第一个是函数表达式,因为它被赋值给一个变量。另外,与函数表达式无关,它是一个匿名函数,因为它没有函数名。第二个是函数声明,因为它不是另一个表达式的一部分,而且是“脚本函数的源元素(脚本中的非嵌套语句或正文函数)”。 (我不太清楚如何解释源元素,所以我从Mozilla文档复制了这个元素)。它还有一个函数名myFunction。此外,该函数也可以在函数声明之前使用,与函数表达式定义的函数不同。

使用函数表达式的以下示例将不起作用:

plusOne(1);
var plusOne = function (x) {
    return x + 1;
};

以下使用函数声明,将起作用:

plusOne(1);
function plusOne(x) {
    return x + 1;
};

另外,看到你看到这个函数声明的链接的主题是闭包,我将继续解释为什么你可以使用函数表达式和匿名函数。有时,函数根本不需要名称,只能是匿名的,因为没有人需要通过名称来调用它。函数表达式可以用于您可能已经学到的东西,称为闭包。闭包是当函数包含变量以便稍后在其中使用时,阻止任何外部作用域到达它。它们有点难以解释,也很难理解,不经过几次各种例子并亲自尝试。

假设你有足够的基本javascript知识(用于循环,创建和附加dom元素,以及onclick),请以下面的代码为例,这类似于我自己发现闭包之前遇到的问题。在不先运行代码的情况下仔细阅读,并尝试找出单击每个按钮/ div时会发生什么。

function addButtons() {
    for (var i=0; i<3; i++) {
        button = document.createElement("div");
        button.innerHTML = "Button " + i;
        button.onclick = function () {
            alert(i);
        };
        document.body.appendChild(button);
    }
}
addButtons();

您可能希望按钮1警告“1”,按钮2警告“2”,按钮3警告“3”。但是,所发生的是所有按钮都会提示“3”。这是因为在变量i已经增加到3之前不会执行onclick。

现在阅读下一段代码。起初看起来有点令人困惑。

function addButtons() {
    for (var i=0; i<3; i++) {
        var button = document.createElement("div");
        button.innerHTML = "Button " + i;
        button.onclick = function (j) {
            return function () {
                alert(j);
            }
        }(i);
        document.body.appendChild(button);
    }
}
addButtons();

如果你运行它,你会发现每个按钮都会提醒你一开始可能会发生什么。按钮1将警告“1”,按钮2将警告“2”,按钮3将警告“3”。所以在这里,onlick返回引用j的闭包,它在for循环期间用i设置。变量j安全地保存在闭包中,与i不同,i在每个循环中都在变化。当然,如果你愿意,你仍然可以命名闭包中使用的函数,但是没有理由。

我不确定我是否完美地解释了这一点,但我希望它至少可以介绍一些新的和有用的东西!您可以在Mozilla Developer Network找到有关函数的更多信息。

答案 3 :(得分:0)

var plusOne = function (x) {
    return x + 1;
};

是一个变量语句,其初始值设定项是函数表达式,而

function plusTwo(x) {
    return x + 2;
}

是一个函数声明。

要理解两者之间的区别,您需要了解变量的初始化方式:

首先,JavaScript变量具有函数作用域(这与大多数其他流行的编程语言不同,其中变量是块作用域的),并且在代码评估之前发生变量声明。

这意味着变量语句在函数体内的位置并不重要:从概念上讲,它与位于顶部的声明相同。

但是,变量将被预先初始化为undefined,并且只有在代码执行期间遇到变量语句时才会分配实际值。

对于函数声明不是这样:函数声明在声明绑定时计算,即在一般代码执行之前计算。

特别是,这意味着在声明之前的语句中调用声明的函数是完全有效的,即这将正常工作:

alert(plusTwo(42));
function plusTwo(x) {
    return x + 2;
};

,而

alert(plusOne(42));
var plusOne = function (x) {
    return x + 1;
};

会失败,因为它在概念上等同于

var plusOne = undefined;
alert(plusOne(42));
plusOne = function (x) {
    return x + 1;
};