JS中 (function(){...})()立即执行函数

时间:2021-07-04 17:13:43
 (function(){...})()
(function(){...}())

这是两种js立即执行函数的常见写法。

基本概念:

函数声明:function fname(){...}; 使用function关键字声明一个函数,再指定一个函数名。

函数表达式:var fname=function(){...}; 使用function关键字声明一个函数,但未给函数命名,最后将匿名函数赋予给一个变量。

匿名函数:function(){}; 使用function关键字声明一个函数,但未给函数命名。(匿名函数也属于函数表达式。)

(匿名函数作用很多,赋予一个变量则创建函数,赋予一个事件则成为事件处理程序等。。)

关于函数声明和函数表达式的区别:

1:函数声明的Function declaration Hoisting(换成人话就是函数声明提升),函数表达式不具备这点,它需要被js代码解析到当前这行时才可以调用。

2:函数表达式后边加 ()立即调用该函数,函数声明不可以,它只能以fname()调用。

例子:

 fName();
function fName(){...}//正确,函数声明提升,所以 fName()可以写在函数声明之前。 fName();
var fName=function(){...}//错误,函数表达式不具备函数声明提升。 var fName=function(){...}();//正确,函数表达式后边加()立即调用函数。 function fName(){...}();//错误,函数声明必须用fName()调用。
//这行代码被解析为两部分: 1函数声明 function fName(){...}, 2分组表达式(),这表达式有误,因为括号内没有表达式, function (){...}();//匿名函数不可以这么调用,因为function(){...}被当做了声明,声明不可以直接()调用。

顺便说下立即调用IIFE(Immediately Invoked Function Expression):

(function(){...})() 和 (function(){...}()) 是没区别的!

传统的定义函数为:

 function foo(){...} //这是定义,Declaration,只是让解释器知道其存在,不会运行

 foo(); //这是语句,解释器遇到语句会运行它

为什么要IIFE呢? 1:传统的方法啰嗦。 2:传统的方法污染全局命名空间

于是 我们这么写  function foo(){...}();  这样写行么。。不行,为啥,因为function foo(){...}这部分只是声明,对解释器来说,像是你写了串字符串“function foo(){...}”,它需要的是解析函数,可以用比如eval()来执行它才可以。所以把()直接放声明后边是不行的,错误语法!

然而,我们距离成功相当接近,只需要把函数声明变成函数表达式就可以了。方法非常多,最常见的方法是用一对() 包裹起来。 (function foo(){...})();

这就等价于

 var foo= function(){...};
foo();

当然 还有很多别的方法可以把声明变成表达式:

  !function foo(){...}();
+function foo(){...}();
void function() {...}();

需要全局对象的时候,可以这么传, 举例:

 void function(global){
console.log("a's value is: "+global.aa); //可以获取全局对象中aa的值
}(this)
 var aa=10;
(function(a){
console.log("hello world"+a);
})(aa);