JS 立即执行函数可以让函数在创建后立即执行,这种模式本质上就是函数表达式(命名的或者匿名的),在创建后立即执行。

1、立即执行函数的写法

立即执行函数通常有下面两种写法:

//第一种写法
(function(){
...
})(); //第二种写法
(function(){
...
}()); //错误的写法
function (){
...
}();    //报错: Uncaught SyntaxError: Unexpected token (

第三种写法报错的原因是,Javascript引擎看到function关键字之后,认为后面跟的是函数定义语句,而在一条语句后面加上() 会被当做分组操作符,分组操作符里必须要有表达式,所以这里报错,不应该以圆括号结尾。以圆括号开头,引擎就会认为后面跟的是一个表示式,而不是函数定义,所以就避免了错误。

让Javascript引擎认为这是一个表达式的方法还有很多:

!function(){}();
+function(){}();
-function(){}();
~function(){}();
new function(){ /* code */ }
new function(){ /* code */ }() // 只有传递参数时,才需要最后那个圆括号

2、立即执行函数的作用

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

面试题:

var liList = ul.getElementsByTagName('li')
for(var i=0; i<6; i++){
liList[i].onclick = function(){
alert(i) // 为什么 alert 出来的总是 6,而不是 0、1、2、3、4、5
}
}

因为输出的 i 是全局作用域的,当循环结束后 i 的值是 6,所以输出的 i 就是6。

用立即执行函数可以解决这个问题。

var liList = ul.getElementsByTagName('li')
for(var i=0; i<6; i++){
(function(j){
liList[j].onclick = function(){
alert(j) // 0、1、2、3、4、5
}
})(i)
}

因为 JS 中调用函数传递参数都是值传递 ,所以当立即执行函数执行时,首先会把参数 i 的值复制一份,然后再创建函数作用域来执行函数,循环5次就会创建5个作用域,所以每个 li 元素访问的都是不同作用域的 i 的值 。

3、立即执行函数和闭包的区别

setTimeout 依次输出 0 1 2 3 4 5

for (var i = 0; i < 5; i++) {
(function (i) {
setTimeout(function () {
console.log(i);
}, 1000);
})(i);
}
console.log(i);

第一个 5 很好输出,因为for循环以后i就会变成5,剩下的我们可以使用立即执行函数来做。首先 JS中调用函数传递参数都是值传递 ,所以当立即执行函数执行时,首先会把参数 i 的值复制一份,然后再创建函数作用域来执行函数,循环5次就会创建5个作用域,所以1秒后几乎会同时输出 0 1 2 3 4 。

上面的现象也可以说是闭包,因为在外层的 function 里面还包含着 setTimeout 里面的 function 函数,而里面的 function 函数就访问了外层 function 的 i 的值,由此就形成了一个闭包。每次循环时,将 i 的值保存在一个闭包中,当 setTimeout 中定义的操作执行时,就会访问对应闭包保存的 i 值,所以输出 0 1 2 3 4。

立即执行函数和闭包没有什么关系,只是两者会经常结合在一起使用而已,但两者有本质的不同。

立即执行函数和闭包只是有一个共同优点就是能减少全局变量的使用。

立即执行函数只是函数的一种调用方式,只是声明完之后立即执行,这类函数一般都只是调用一次,调用完之后会立即销毁,不会占用内存。

闭包则主要是让外部函数可以访问内部函数的作用域,也减少了全局变量的使用,保证了内部变量的安全,但因被引用的内部变量不能被销毁,增大了内存消耗,使用不当易造成内存泄露。

可参考:https://blog.csdn.net/Liu_yunzhao/article/details/90641956

JS中的立即执行函数的更多相关文章

  1. JS中的自执行函数

    本来规划的是2013年,狠狠的将JS学习下,谁知计划赶不上变化,计划泡汤了.13年的我对JS来说可以说是属于跟风,对它的理解和认识也仅仅是皮毛而已,也是因为要完成<ArcGIS API for ...

  2. JS中 (function(){...})()立即执行函数

    (function(){...})() (function(){...}()) 这是两种js立即执行函数的常见写法. 基本概念: 函数声明:function fname(){...}; 使用funct ...

  3. 【repost】js中(function(){…})()立即执行函数写法理解

    摘要: javascript和其他编程语言相比比较随意,所以javascript代码中充满各种奇葩的写法,有时雾里看花,当然,能理解各型各色的写法也是对javascript语言特性更进一步的深入理解. ...

  4. js中(function(){…})()立即执行函数写法理解

    文章摘自https://my.oschina.net/u/2331760/blog/468672?p={{currentPage+1}} 摘要: javascript和其他编程语言相比比较随意,所以j ...

  5. js中(function(){…})()立即执行函数写法理解(转载oschina)

    ( function(){…} )()和( function (){…} () )是两种javascript立即执行函数的常见写法,最初我以为是一个括号包裹匿名函数,再在后面加个括号调用函数,最后达到 ...

  6. 深入理解js中的立即执行函数(function(){…})()

    javascript和其他编程语言相比比较随意,所以javascript代码中充满各种奇葩的写法,有时雾里看花,当然,能理解各型各色的写法也是对javascript语言特性更进一步的深入理解. ( f ...

  7. js中的延迟执行和定时执行

    在js中,延迟执行函数有两种,setTimeout和setInterval,用法如下: function testFunction(){Console.log('hovertree.com');} s ...

  8. IIFE-js中(function(){…})()立即执行函数写法理解

    介绍IIFE IIFE的性能 使用IIFE的好处 IIFE最佳实践 jQuery优化 在Bootstrap源码(具体请看<Bootstrap源码解析>)和其他jQuery插件经常看到如下的 ...

  9. [转]js中confirm实现执行操作前弹出确认框的方法

    原文地址:http://www.jb51.net/article/56986.htm 本文实例讲述了js中confirm实现执行操作前弹出确认框的方法.分享给大家供大家参考.具体实现方法如下: 现在在 ...

随机推荐

  1. 虚拟机中安装Linux_Centos7操作系统(最小化安装)

    我们打开之前安装的VM, 点击 “创建新的虚拟机”: 我们选 典型 安装  简单点 然后下一步: 我们稍后安装操作系统 ,点下一步: 这里选 Linux 然后下拉 选CentOS 64位,然后下一步: ...

  2. 【BASIS系列】SAP 设置系统timeout时间

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[BASIS系列]SAP 设置系统timeout ...

  3. Bootstrap 学习笔记5 进度条媒体对象和well组件

    代码: <ul class="media-list"> <li class="media"> <div class="m ...

  4. shell 删除项目日志

    删除半年之前的日志 find 后面紧跟目录 .为当前目录 -type f 指定查找的是文件 -mtime +180  查找180天之前的 -name  文件名筛选 -exec -rm -rf  执行的 ...

  5. knn原理及借助电影分类实现knn算法

    KNN最近邻算法原理 KNN英文全称K-nearst neighbor,中文名称为K近邻算法,它是由Cover和Hart在1968年提出来的 KNN算法原理: 1. 计算已知类别数据集中的点与当前点之 ...

  6. 线段树(two value)与树状数组(RMQ算法st表)

    士兵杀敌(三) 时间限制:2000 ms  |  内存限制:65535 KB 难度:5 描述 南将军统率着N个士兵,士兵分别编号为1~N,南将军经常爱拿某一段编号内杀敌数最高的人与杀敌数最低的人进行比 ...

  7. 洛谷 P5019 铺设道路 & [NOIP2018提高组](贪心)

    题目链接 https://www.luogu.org/problem/P5019 解题思路 一道典型的贪心题. 假设从左往右填坑,如果第i个深与第i+1个,那么第i+1个就不需要额外填: 如果第i+1 ...

  8. python学习第六天--匿名函数、过滤、映射

    匿名函数 lambda表达式 过滤器 filter(判断函数,可迭代对象) 会根据提供的函数对指定序列做过滤 映射 map(判断函数,可迭代对象) 会根据提供的函数对指定序列做映射

  9. K3 cloud选单时候必须把必录的数据录完以后才可以选单

    解决办法:在bos中把选单按钮的提交时候校验打勾

  10. console.log的高级用法

    //基本用法 console.log('最常见用法\n换行'); console.error('输出错误信息 会以红色显示'); console.warn('打印警告信息 会以黄色显示'); cons ...