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. log4J——在Spring中的使用

    log4J简介 1.通过 log4j 可以看到程序运行过程中更详细的信息 (1)经常使用 log4j 查看日志 2.使用 (1)导入 log4j 的jar包 (2)复制 log4j 的配置文件,复制到 ...

  2. java中的VO、PO、BO、DAO、POJO

     针对java工程里的各种带O的对象,进行分析,了解各自的作用. PO: persistent object,持久对象.与数据库里表字段一一对应.PO是一些属性,以及set和get方法组成.一般情况下 ...

  3. 剑指Offer9——使用双栈模拟队列

    剑指Offer9--使用双栈模拟队列 队列Queue是具有FIFO(First in First out)特性的数据结构,栈Stack是具有LIFO(后进先出)特性的数据结构.下面提供一种思路使用双栈 ...

  4. 7. Github Pages 搭建网站

    7. Github Pages 搭建网站 个人站点 访问 https://用户名.github.io 搭建步骤 1) 创建个人站点   ->  新建仓库(注:仓库名必须是[用户名.github. ...

  5. 7_线性控制器设计(Linear Controller Design)

    开环系统中 状态方程,其中A的特征值将决定这个系统的表现(稳定性或者收敛速度:特征值小于0时系统稳定) 如果开环系统特征值大于0时(即系统不稳定时): 可以引入输入量U时(U是关于状态变量X的函数), ...

  6. 顺利通过EMC实验(4)

  7. Git使用方法以及出现的bug解决方案

    git常用命令 1.本地库初始化: git init 2.设置签名 (1)项目级别(项目里面) git config user.name xxx git config user.email xxx ( ...

  8. JavaScript一些重要知识点结合题目的表现!

    function Foo() { //① 声明一个Foo的函数 getName = function () { alert (1); }; return this; } Foo.getName = f ...

  9. FastAPI(六十七)实战开发《在线课程学习系统》接口开发--用户登陆接口开发

    接上一篇文章FastAPI(六十六)实战开发<在线课程学习系统>接口开发--用户注册接口开发.这次我们分享实际开发--用户登陆接口开发. 我们先来梳理下逻辑 1.查询用户是否存在2.校验密 ...

  10. EbitenCookBook中文教程 第一课:安装 Ebiten

    本文实时更新原址:https://ebitencookbook.vercel.app/docs/CookBook_Start/class1 第一课 安装 Ebiten 欢迎大家来到 Ebiten 中文 ...