函数声明,函数表达式,立即执行函数表达式。

我们定义一个函数,一般有两种方法

  1. 函数声明
function fnName(){...};              
  1. 函数表达式
var fn = function fnName(){...}

声明函数后,我们可以使用fnName ()来调用这个函数

function f1(){
    console.log('函数声明')
}             
f1()
//输出:函数声明。
var f1 = function f2(){
    console.log('函数声明')
}
f1()
//输出:函数表达式。

那么我们可不可以直接在后面加()直接调用这个函数呢?

function f1(){
    console.log('函数声明')
}()
// 报错 SyntaxError: Unexpected token (
var f1 = function f2(){
    console.log('函数声明')
}()
//输出 函数声明

为什么会这样呢,原来,JavaScript解释器会在默认的情况下把遇到的function关键字当作是函数声明语句(statement)来进行解释的,所以第一种写法是有语法错误的。

这时我们可以总结出两种函数声明方式的不同

  • Javascript引擎在解析javascript代码时会'函数声明提升'(Function declaration Hoisting)当前执行环境(作用域)上的函数声明,而函数表达式必须等到Javascirtp引擎执行到它所在行时,才会从上而下一行一行地解析函数表达式。
  • 函数表达式后面可以加括号立即调用该函数,函数声明不可以,只能以fnName()形式调用 。
所以,要在函数体后面加括号就能立即调用,则这个函数必须是函数表达式,不能是函数声明。

一个匿名函数想立即执行就需要把它变成一个表达式,这就是立即执行函数表达式。

(function(){alert('我是匿名函数')} ()) // 用括号把整个表达式包起来
(function(){alert('我是匿名函数')}) () //用括号把函数包起来

所以根据上面的解释,我们知道只要能让JavaScript引擎以「函数表达式」而不是「函数声明」来处理匿名函数的立即执行就可以了,把语句放在()之中只是其中的一种方法而已,根据这个思路我们可以用其他方式来实现同样的目的,比如:

!function(){alert('我是匿名函数')}() // 求反,我们不在意值是多少,只想通过语法检查。
+function(){alert('我是匿名函数')}()
-function(){alert('我是匿名函数')}()
~function(){alert('我是匿名函数')}()
void function(){alert('我是匿名函数')}()
new function(){alert('我是匿名函数')}()

立即执行函数表达式有什么作用呢?

只有一个作用:创建一个独立的作用域。
这个作用域里面的变量,外面访问不到(即避免「变量污染」)。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容