首页 技术 正文
技术 2022年11月18日
0 收藏 790 点赞 3,724 浏览 1382 个字

先提个问题,

单独写匿名函数为什么报错?return 匿名函数 为什么不报错?

如图:

第二种情况在 f 还没有执行的时候,就报错了,,,当然这得归因于函数声明语句声明提前(发生在代码执行之前)的原因;

先说下高程下匿名函数的定义:

匿名函数(anonymous function),function 关键字后面没有标识符,(匿名函数有时候也叫拉姆达函数。)匿名函数的name 属性是空字符串。

在把函数当成值来使用的情况下,都可以使用匿名函数。

回答开头的问题:

单独写匿名函数为什么报错?

高程上说:因为JavaScript 将function 关键字当作一个函数声明语句的开始,而函数声明语句 function 关键字后面应该是 函数名,这里后面跟圆括号,当然会报错。

换一种理解就是:解析器可以把它当作匿名函数表达式,也可以当做函数声明语句去解析,但是默认情况下,是当成函数声明语句去解析的,所以这个时候会报错,除非在某些位置只能当做表达式去解析,就不会有歧义报错了;

return 匿名函数 为什么不报错?

根据 MDN 上的解释:

return语句终止函数的执行,并返回一个指定的值给函数调用者。

return [[expression]]; 

表达式的值会被返回。如果忽略,则返回 undefined

The expression whose value is to be returned. If omitted, undefined is returned instead.

所以,猜测 js 引擎把 return 后面的内容当成 表达式 去解析,在这里就是把匿名函数当成表达式去解析,自然就不会报错了。

同样的道理,下面代码也不会报错,并且正确执行:

因为 var 声明的 = 后面跟着的应该是表达式,所以 js 引擎把后面的内容当做匿名函数表达式去解析,这样,在函数表达式之后,加上(),自然就是调用函数了,这也没什么问题。

所以,在有歧义的地方,我们需要消除歧义,告诉解析器把 匿名函数表达式 当成 表达式 去解析,而不是采取默认的函数声明语句;

方法:
高程说:加个括号()就可以了,如图;

这样就可以消除歧义,标注()里的是表达式,而不是语句;

既然已经转成函数表达式了,那么在函数表达式后面加上(),

自然就是执行函数了,这就是大名鼎鼎的立即调用的函数表达式(IIFE),也称自执行函数。

举一反三,换个格式:

逻辑上也是一样,因为外面有大括号,所以 js 引擎会把里面的内容作为表达式去解析,而不是作为语句去执行(因为函数调用也是表达式)。

这就与 ES6 之前的模块化联系起来了,

var module1=(function() {
// 把涉及的变量都放在这个匿名函数内,避免了全局变量污染问题;
var i = 0; function(x) {
return x + 1
}
})();

这个代码是不是很熟悉?如果不关心最外层的匿名函数的返回值或不怕难以阅读,也就是 module1 的值,你可以在匿名函数括号外加上一些其他符号,只要不影响内部函数的运行就行了,常见的有:

!function () { /* code */ } ();
~function () { /* code */ } ();
-function () { /* code */ } ();
+function () { /* code */ } ();

参考资料:

JavaScript高级程序设计-第3版-中

JavaScript权威指南-第6版-中

更多:

深入理解JavaScript系列(4):立即调用的函数表达式

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:8,964
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,486
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,331
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,114
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,747
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,781