js 匿名函数-立即调用的函数表达式
先提个问题,
单独写匿名函数为什么报错?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,
undefinedis 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系列(4):立即调用的函数表达式
js 匿名函数-立即调用的函数表达式的更多相关文章
- LR常用函数以及调用自定义函数
2.LR常用函数以及调用自定义函数 2.1.LR常用函数以及对信息的判断 2.1.1. LR内部自定义函数 在LR脚本中定义变量和编写自定义函数,需将变量的声明放在脚本其他内容的上方,否则会提示[il ...
- python27期day09:函数的初始、函数的定义、函数的调用、函数的返回值、函数的参数、作业题。
1.函数的作用:封装代码.大量的减少了重复的代码. 2.全局空间:顶行写的就是全局空间. 图解 : 3.函数的定义: def 是一个关键字.申明要定义一个函数 my_len 函数的名字.遵循变量命名的 ...
- Python基础(函数,函数的定义,函数的调用,函数的参数,递归函数)
1.函数 我们知道圆的面积计算公式为: S = πr2 当我们知道半径r的值时,就可以根据公式计算出面积.假设我们需要计算3个不同大小的圆的面积: r1 = 12.34 r2 = 9.08 r3 = ...
- 在成员函数中调用虚函数(关于多态的注意事项)------新标准c++程序设计
类的成员函数之间可以互相调用.在成员函数(静态成员函数.构造函数和析构函数除外)中调用其他虚成员函数的语句是多态的.例如: #include<iostream> using namespa ...
- Python---7函数(调用&定义函数)
函数 Python内置了很多有用的函数,我们可以直接调用. 要调用一个函数,需要知道函数的名称和参数,比如求绝对值的函数abs(),只有一个参数.可以直接从Python的官方网站查看文档: http: ...
- JavaScript中函数引用调用和函数直接调用的区别
首先看下面的代码: var x = 1 var f1 = function( f ) { var x = 2 ; f( ' console.log( x ) ' ) } var f2 = funct ...
- java如何在函数中调用主函数的数组
import javax.swing.JOptionPane; public class Test { /** * @zdz */ public static void main(String[] a ...
- 写一方法计算实现任意个整数之和.在主调函数中调用该函数,实现任意个数之和。(使用params参数)
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- daemon_init函数:调用该函数把普通进程转变为守护进程
#include <unistd.h> #include <syslog.h> #include <fcntl.h> #include <signal.h&g ...
随机推荐
- Mybatis(六):spring与mybatis三种整合方法
1.采用MapperScannerConfigurer,它将会查找类路径下的映射器并自动将它们创建成MapperFactoryBean. spring-mybatis.xml: <?xml ve ...
- [k8s]helm原理&私有库搭建&monocularui和kubeapp探究
运行最简单的charts示例 helm的2个chart例子: https://github.com/kubernetes/helm/tree/master/docs/examples/nginx he ...
- location if (.....) #if与中括号之间要有空格
[root@web01 default]# /app/server/nginx/sbin/nginx -t nginx: [emerg] unknown directive nginx: config ...
- bootstrap.memory_lock: true导致Elasticsearch启动失败问题
elasticsearch官网建议生产环境需要设置bootstrap.memory_lock: true 重新启动elasticsearch,报错信息如下: [baoshan@test-43.dev. ...
- linux超级终端minicom的使用方法
===== 一.Minicom介绍 ===== Linux下的Minicom的功能与Windows下的超级终端功能相似,可以通过串口控制外部的硬件 设备.适于在linux通过超级终端对 ...
- 基于jQuery select下拉框美化插件
分享一款基于jQuery select下拉框美化插件.该插件适用浏览器:IE8.360.FireFox.Chrome.Safari.Opera.傲游.搜狗.世界之窗.效果图如下: 在线预览 源码下 ...
- 一款jquery和css3实现的卡通人物动画特效
之前为大家分享了很多jquery和css3的动画实例.今天给大家带来一款非常炫的jquery和css3实现的卡通人物动画特效.效果图如下: 在线预览 源码下载 实现的代码. html代码: < ...
- Odoo 8.0 new API 之constrains装饰
constrains装饰用于对字段进行限制 应用举例: 定义列: age = fields.Integer(string="age") 方法: @api.constrains('a ...
- Genymotion常见问题整合与解决方案(转)
常见问题1:Genymotion在开启模拟器时卡在了starting virtual device(注意只有tarting virtual device窗口,没有模拟器的黑屏窗口) 原因:Vir ...
- mysql 分区 限制
MySQL分区的限制 • 只能对数据表的整型列进行分区源码天空,或者数据列可以通过分区函数转化成整型列 • 最大分区数目不能超过1024 • 如果含有唯一索引或者主键,则分区列必须包含在所 ...