理解 javascript 中的函数表达式与函数声明
作者:mdxy-dxy 时间:2024-04-23 09:08:26
常用闭包的同学肯定很清楚下面一段代码:
//通常的闭包写法
(function () {
...
}())
那么我们的问题来了,为什么要在 function () {...}() 之外用圆括号包裹呢?解答这个问题,就需要我们理解 Javascript 中函数表达式与函数声明的概念。
函数定义带来的错误
虽然 function () {...} 看上去像是一个函数声明,但是由于没有函数名,它的本质其实是一个函数表达式。我们看下规范中对于函数声明与函数表达式的定义:
可以看出来,函数声明是必须带有函数名的。所以在直接执行 function () {...}() 时候会报语法错误,原因就是函数表达式被尝试解析为函数声明时没有找到函数名。
那么我们继续尝试写上函数名的情况:
function fn () {...}()
仍然会提示语法错误,不过这次的出错的位置在后面 () 中的 ) 上。
先不解释为什么,看接下来的示例:
从这个结果可以看出,函数声明之后的 () 会被解析为分组运算符,而不是函数调用。那么如何才能使函数执行呢?
如何正确解析函数表达式
根据规范,函数表达式必须在 Expression 中才能进行正确的语法解析。恰巧 () 在作为分组运算符时,里面的内容会被认为是 Expression。
(function () {...}())
(function () {...})()
上述两种写法都是正确的。第一种写法比较清晰,函数表达式被正确解析并调用。第二种写法中,解析器首先处理 (function () {...}) 部分,由于分组运算符不会对其中内容进行 GetValue 操作,所以在语句结束时,其中的函数表达式被直接返回,之后的 () 则表示函数调用。
我们来简单的用一个例子表示一下:
var a = function () {...}
(a()) //形同 (function () {...}())
(a)() //形同 (function () {...})()
这个例子稍有不恰当,因为直接执行 a() 是可行的,而直接执行 function () {...}()
则不行,原因就是上面提到的,function () {...}
被尝试解析为函数声明而引发了语法错误。
其他方式
上面我们提到通过 () 分组运算符,可以将匿名函数正确的理解为函数表达式。同理,我们也可以通过许多其他的运算符将函数表达式正确执行。
!function () {}()
void function () {}()
+function () {}()
-function () {}()
if (function () {}()) {}
...
由于很多操作符会改变函数返回值,比如 !function () {return 0}
,void function () {}()
,+ function () {}()
等,所以我们一般使用 () 将匿名函数包裹使其被正确解析为函数表达式。
参考文章
http://www.zhihu.com/question/40902815/answer/88787368
http://www.zhihu.com/question/20292224


猜你喜欢
使用Python 统计高频字数的方法
搞定web设计中网页路径问题
asp使用 sql_dmo 添加新数据库代码
Python图片处理模块PIL操作方法(pillow)
python 实现 pymysql 数据库操作方法
Pandas 多进程处理数据提高速度

Python列表生成器的循环技巧分享

在pycharm中显示python画的图方法

MySQL 有关MHA搭建与切换的几个错误log汇总

ASP连接MySQL数据库代码示例
Python装饰器限制函数运行时间超时则退出执行
PHP正则匹配到2个字符串之间的内容方法
aspjpeg 添加水印教程及生成缩略图教程
vue前端项目打包成Docker镜像并运行的实现

SQL Server Alwayson创建代理作业的注意事项详解

PHP常量及变量区别原理详解

Python Mysql数据库操作 Perl操作Mysql数据库
Python实现XML文件解析的示例代码
详谈python read readline readlines的区别
