IT修真院-前端

JAVASCRIPT的匿名函数

2017-12-30  本文已影响3人  仿佛锋

大家好,我是IT修真院深圳分院第04期学员,一枚正直善良的web程序员。

今天给大家分享一下,修真院官网 js任务中可能会使用到的知识点:

JAVASCRIPT的匿名函数


1.背景介绍

在了解什么是匿名函数之前先要了解声明函数和函数表达式

函数声明

关于函数声明,它最重要的一个特征就是函数声明提升,意思是执行代码之前先读取函数声明。 这意味着可以把函数声明放在调用它的语句之后。如下代码可以正确执行

函数表达式

这种形式看起来好像是常规的变量赋值语句。 但是函数表达式和函数声明的区别在于,函数表达式在使用前必须先赋值。 所以一下代码执行的时候就会出错:

造成这种现象是因为解析器在向执行环境中加载数据时,解析器会率先读取函数声明,并使其在执行任何代码前可用; 至于函数表达式,则必须等到解析器执行到它的所在的的代码行,才会真正的被解析。

函数表达式中,function关键字后面没有标识符,创建的函数叫做匿名函数。


2.知识剖析

匿名函数的调用方式

匿名函数,顾名思义就是没有名字的函数。例如我们在设定一个DOM元素事件处理函数的时候,我们通常都不会为他们定名字,而是赋予它的对应事件引用一个匿名函数。 上面的函数表达式中的创建,即创建一个匿名函数,并将匿名函数赋值给变量ss,用ss来进行函数的调用, 调用的方式就是在变量ss后面加上一对括号(),如果有参数传入的话就是ss(4,6),这就是匿名函数的一种调用方式。 还有一种匿名函数的调用方式是:使用()将匿名函数括起来,然后后面再加一对小括号(包含参数列表)。我们再看一下以下一个例子:

在javascript中,是没有块级作用域这种说法的,以上代码的这种方式就是模仿了块级作用域(通常成为私有作用域),语法如下所示:

语句结束函数执行,返回调用函数,而且把表达式的值作为函数的结果。

以上代码定义并立即调用了一个匿名函数。经函数声明包含在一对圆括号中, 表示它实际上是一个函数表达式。而紧随其后的另一对圆括号会立即调用这个函数。

然而要注意一点:

上面的代码是错误的,因为Javascript将function关键字当作一个函数声明的开始,而函数声明后面不能加圆括号, 如果你不显示告诉编译器,它会默认生成一个缺少名字的function,并且抛出一个语法错误,因为function声明需要一个名字。 有趣的是,即便你为上面那个错误的代码加上一个名字,他也会提示语法错误,只不过和上面的原因不一样。 在一个表达式后面加上括号(),该表达式会立即执行,但是在一个语句后面加上括号(),是完全不一样的意思,他的只是分组操作符。

所以上面代码要是想要实现,就必须要实现赋值,如a = function(){}(), "a="这个告诉了编译器这个是一个函数表达式,而不是函数的声明。 因为函数表达式后面可以跟圆括号。所以下面两段代码是等价的。

有上面对于函数和匿名函数的了解,我们引申出来了一个概念,即自执行函数,让我们更加深入的了解为什么。 a = function(){}()这个表示可以让编译器认为这个是一个函数表达式而不是一个函数的声明。


3.常见问题

大家看到这里会有疑问,刚刚那些不是自执行函数吗?

接下来会为大家解答什么是自执行函数?


4.解决方案

我们创建了一个匿名的函数,并立即执行它,由于外部无法引用它内部的变量,因此在执行完后很快就会被释放,关键是这种机制不会污染全局对象。 自执行函数,即定义和调用合为一体。下面我们来看下一下自执行函数的表达方式


5.扩展思考

闭包

闭包是什么?闭包是指某种程序语言中的代码块允许一级函数存在并且在一级函数中所定义的自由变量能不被释放, 直到一级函数被释放前,一级函数外也能应用这些未释放的自由变量。

怎样?看得一头冒汗吧……没事。让我们换个更加简单的方法说明:闭包,其实是一种语言特性, 它是指的是程序设计语言中,允许将函数看作对象,然后能像在对象中的操作搬在函数中定义实例(局部)变量,而这些变量能在函数中保存到函数的实例对象销毁为止, 其它代码块能通过某种方式获取这些实例(局部)变量的值并进行应用扩展。

不知道这么再解释后会否更加清晰,如果还是不明白,那么我们再简化一下:闭包,其实就是指程序语言中能让有权访问另一个函数作用域中的变量的函数。


6.参考文献

参考1:对JAVASCRIPT匿名函数的理解(透彻版)

参考2:杂七杂八JS :深入理解 函数、匿名函数、自执行函数


7.更多讨论

问题1:把匿名函数赋值给变量ss 每次调用变量ss是否都会执行一次匿名函数?

答:是的。

要注意必须先把匿名函数付给变量,然后再去执行

问题2:-function(){console.log(1);}()的结果为什么也是1?

答:因为由于括弧()和JS的&&,!,逗号等操作符是在函数表达式和函数声明上消除歧义的 ,所以一旦解析器知道其中一个已经是表达式了,其它的也都默认为表达式了  

问题3:闭包函数内部return 一个匿名函数,这个匿名函数的this指向哪一个对象

第一题 第二题

答:第一题this指的是window

       第二题this指的是object


JAVASCRIPT的匿名函数

感谢大家观看!

今天的分享就到这里啦,欢迎大家点赞、转发、留言、拍砖!

上一篇下一篇

猜你喜欢

热点阅读