JS 的立即执行函数

本文写于 2019 年 12 月 7 日

其实 ES6 之后有了之后,很多之前的用法都没必要了,立即执行函数就是其一。

今天看到一道面试题:

请「用自己的语言」简述

  1. 立即执行函数是什么
  2. 立即执行函数有什么用途

我愣了一下,突然发现自己不是很能清晰的解答这个概念。

我只知道()代表了两种作用:

  • 包裹
  • 执行函数

立即执行函数该怎么描述呢?

声明一个匿名函数,然后马上调用这个匿名函数,就是立即执行函数?

的确,这就是一个典型的立即执行函数。

首先声明一个匿名函数: function(){ alert(‘我是匿名函数’) }

然后在匿名函数后面接一对括号 (),调用这个匿名函数。

那么为什么还要用另一对括号把匿名函数包起来呢?

其实是为了兼容 JS 的语法。

如果我们不加另一对括号,直接写成:

function(){
alert('我是匿名函数')
}()

浏览器会报语法错误!

想要通过浏览器的语法检查,必须加点小东西,比如下面几种

;(function () {
alert('我是匿名函数')
})()(
// 用括号把整个表达式包起来
function () {
alert('我是匿名函数')
}
)() //用括号把函数包起来
!(function () {
alert('我是匿名函数')
})() + // 求反,我们不在意值是多少,只想通过语法检查。
(function () {
alert('我是匿名函数')
})() -
(function () {
alert('我是匿名函数')
})()
~(function () {
alert('我是匿名函数')
})()
void (function () {
alert('我是匿名函数')
})()
new (function () {
alert('我是匿名函数')
})()

目前我也不是很清楚为什么,但是这些都是实验证明不会报错的写法。(所以大家都说 JS 诡异)

立即执行函数有什么用呢?

只有一个作用:创建一个独立的作用域。

这个作用域里面的变量,外面访问不到(即避免「变量污染」)。

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
}
}

为什么 alert 的总是 6 呢,因为 i 是贯穿整个作用域的,而不是给每个 li 分配了一个 i!

怎么解决这个问题呢?

用立即执行函数给每个 li 创造一个独立作用域即可:

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

在立即执行函数执行的时候,i 的值被赋值给 ii,此后 ii 的值一直不变。

i 的值从 0 变化到 5,对应 6 个立即执行函数,这 6 个立即执行函数里面的 ii 「分别」是 0、1、2、3、4、5。

但是这是用var声明,如果使用了let,不会出现这种问题!!!!!!

这就是立即执行函数的基本概念。

(完)

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

  1. js匿名自执行函数中闭包的高级使用(---------------------------******-----------------------------)

    先看看最常见的一个问题: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> ...

  2. JS中立即执行函数的理解

    1.匿名函数不能单独定义,必须进行赋值操作或者立即执行,否则会被JS引擎定义为语法错误 function(){alert(dada);} VM229:1 Uncaught SyntaxError: U ...

  3. js中立即执行函数写法理解

    在理解了一些函数基本概念后,回头看看( function(){…} )()和( function (){…} () )这两种立即执行函数的写法,最初我以为是一个括号包裹匿名函数, 并后面加个括号立即调 ...

  4. js匿名自执行函数

    匿名自执行函数:没有方法名的函数闭包:闭包是指有权访问另一个函数作用域变量的函数: 通过一个实例来解释: 从网上找到了一个案例,使用了for循环.匿名自执行函数.setTimeout. 案例1: va ...

  5. js的立即执行函数

    立即执行函数:常用于第三方库,好处在于隔离作用域,任何一个第三方库都会存在大量的变量和函数,为了避免变量污染(命名冲突),一般想到的方法就是使用立即执行函数.jQuery就是使用的立即执行函数. 函数 ...

  6. 【原】js离开页面执行函数 onbeforeunload与onunload事件

    在最近的项目中,需要做到一个时间,就是用户离开页面的时候,我需要缓存页面其中一部分的内容,但是我不需要用户刷新的时候也缓存,我只希望在我用户离开的时候 执行这个函数.百度之,有onbeforeunlo ...

  7. js中自执行函数(function(){})()和(function(){}())区别

    方式一,调用函数,得到返回值.强制函数直接量执行再返回一个引用,引用在去调用执行方式二,调用函数,得到返回值.强制运算符使函数调用执行(function(){})(); 是 把函数当作表达式解析,然后 ...

  8. js自定义延迟执行函数

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...

  9. js中自执行函数写法

    //自执行写法1 (function T(){ alert(1) })() //自执行写法2 var T1=function(){ alert(1) }(); //传值 var para1={a:1; ...

随机推荐

  1. python面向对象--快速入门

    1面向对象基本用法 1.1基本格式 class 类名: def __init__(self,x): self.x = x def 方法名字 (self): #函数在类里称为方法,self就是固定参数, ...

  2. 学习ELK日志平台(三)

    ELK(elasticsearch.logstash.kibana) Elastic Stack是原ELK Stack在5.0版本加入Beats套件后的新称呼 解决痛点: 开发人员不能登录线上serv ...

  3. 学习saltstack (二)

    saltstack使用教程: 1.安装: 需要epel的yum源,没有的话把下面的复制并新建个文件 /etc/yum.repos.d/epel.repo 粘贴即可: [epel] name=Extra ...

  4. ROS终端中创建功能包的常用命令

  5. 在VisualStudio调试器中使用内存窗口和查看内存分布

    调试模式下内存窗口的使用 在调试期间,"内存"窗口显示应用使用的内存空间.调试器窗口(如"监视"."自动"."局部变量" ...

  6. H5新增API

    H5新增API 选择器 querySelector()和querySelectorAll(),参数都是css选择器,前者返回符合条件的第一个匹配的元素,如果没有则返回Null,后者返回符合筛选条件的所 ...

  7. CCF201503-1图像旋转

    问题描述 旋转是图像处理的基本操作,在这个问题中,你需要将一个图像逆时针旋转90度. 计算机中的图像表示可以用一个矩阵来表示,为了旋转一个图像,只需要将对应的矩阵旋转即可. 输入格式 输入的第一行包含 ...

  8. GUI-适配器设计模式-事件处理

    GUI(布局管理器)* FlowLayout(流式布局管理器) * 从左到右的顺序排列. * Panel默认的布局管理器.* BorderLayout(边界布局管理器) * 东,南,西,北,中 * F ...

  9. 一篇文章带你整明白HTTP缓存知识

    最近看了很多关于缓存的文章, 每次看完,看似明白但是实际还是没明白,这次总算搞明白协商缓存是怎么回事了 首先,服务器缓存分强制缓存和协商缓存(也叫对比缓存) 强制缓存一般是服务端在请求头携带字段Exp ...

  10. px,rem,em 通过媒体查询统一的代码

    @media only screen and (max-width: 1080px), only screen and (max-device-width:1080px) { html,body { ...