5

首先 - 是的,我知道有很多关于这个的帖子,或者至少是非常相似的帖子。浏览了那些我仍然没有找到我正在寻找的答案:

我了解到在 javascript 中创建函数有两种主要方法:

var test = function(a){
   console.log(a);
}

这是在运行时创建的,并且:

function test(a){
    console.log(a);
}

这是在运行时之前创建的。

今天看到这个:

(function test(a){
    console.log(a);
})();

我以前从未见过。这个和上面两个有什么区别?

4

3 回答 3

3

这是立即调用函数,它会在声明后立即调用自己。

您可以在 wikipedia上阅读有关立即调用函数表达式的更多信息。

于 2013-11-05T13:33:49.907 回答
2

您的函数示例将在 Javascript 中被视为如下:

  1. 函数表达式
  2. 函数声明
  3. 立即调用函数也称为立即调用函数表达式“IIFE”和自执行匿名函数。

在您所谓的“运行时”中发生的事情是两件事。Javascript 引擎对您的代码进行两次传递。第一遍可以称为声明遍,其中标识了变量和函数声明。然而,在第一遍中,变量发生了一件有趣的事情,它们被称为“提升”但未初始化。第二遍是执行遍。这就是我认为您所说的“运行时”中发生的两件事。

将发生的第一个函数与变量发生的行为相同,因为它被分配给一个变量,它将被“提升”到其函数上下文的顶部并声明但未初始化。所以 JS 会知道它是一个变量,但它被识别为未定义,直到它到达说“哦”的代码部分,将这个变量初始化为一个函数。所以你必须等到初始化步骤之后才能使用。

/* This is how function expression looks after 
   first pass identified but not assigned(initialized) to function 
   its hoisted and undefined just like a reg variable. */

var test;

//test is undefined here    
console.log(test); 

//test is initialize here
var test = function (a) {
  console.log(a);
}

//test is recognized as a function here
console.log(test);

第二个函数将在第一遍中被声明(识别)为函数,你可以使用它,因为 JS 会正确地知道这个函数是一个函数。

//this is recognized as function
console.log(test);

 function test (a) {
   console.log(a);
}

//test is recognized as function here as well
console.log(test);

第三个函数将在第一遍声明后立即执行并创建它自己的执行上下文,自包含。

//test is not recognized here
console.log(test); 

(function test(a) {
  console.log(a);

  //surprise test is recognized here
  console.log(test);
})();

//test is not recognized here
console.log(test);

您还有匿名函数和命名函数表达式。函数在 JS 中非常强大。编码快乐!!

于 2013-11-05T16:54:28.440 回答
2

它们的不同之处在于前两个只定义了函数,而最后一个定义并执行了函数。最后一个的典型用途是减少全局命名空间污染,因为变量将作用于函数而不是窗口。

于 2013-11-05T13:51:11.857 回答