前端进阶|第九天 逆天的立即执行函数(IIFE)

简介: 前端进阶|第九天 逆天的立即执行函数(IIFE) 每天一个知识点

不多说,先看两道笔试题,首先上代码。
例1

    <script>
        window.onload = function () {
            var list = document.getElementsByClassName('list')
            for (var i = 0; i < list.length; i++) {
                list[i].addEventListener('click', function () {
                    alert(i);
                })

            }
        }      
    </script>
    <ul>
        <li class="list">点我1</li>
        <li class="list">点我2</li>
        <li class="list">点我3</li>
    </ul>

按照逻辑应该实现的效果是,我们点击每个元素,弹框提示对应元素的索引值,但真实的结果是无论我们点击哪个li,均弹出3.
例2来自京东的笔试题,代码如下

       var name = 'Tom';
        (function () {
            if (typeof name == 'undefined') {
                name = 'Jack';
                console.log('Goodbye ' + name);
            } else {
                console.log('Hello ' + name);
            }
        })();

如果我们不了解IIFE的执行逻辑,可能会认为输出是Hello Tom,然而程序的实际输出是Goodbye Jack。
要解决这两道题目,我们就要去搞明白IIFE的相关内容。
1 何为IIFE
IIFE( 立即调用函数表达式)顾名思义是一个在定义时就会立即执行的  [JavaScript]。
语法格式如下

 (function(){
            alert('hello world')
        })();

这两行代码完成了两个功能,声明了一个函数,并自己进行了调用。简单来说,我们以往定义的函数,如果要执行是需要调用的,可能是事件触发,也可能是我们直接调用。但IIFE明显独树一帜,完成声明后,自己调用执行自己,非常独立和自我。
2.IIFE的作用
解决了“我是谁 ”的问题,接着来看IIFE存在的意义是什么。
1)因为IIFE的执行是自主完成的,所以我们无需为其命名,这样可以避免全局性的变量污染。
2)IIFE圈地自治,IIFE函数体内的变量只在本作用域内有效,可以有效减少变量污染,同时实现变量私有,函数执行完成后,变量立即销毁。
3.如何使用IIFE
回到第一题,之所以会输出3,是因为点击函数并不是立即执行的,变量i的值在for循环里是在不断变化的,当for循环执行后,i的最终值为3,那么点击元素出发弹框后,会自动访问i的地址,找到的就是3。
使用立即执行函数可以有效解决这个问题。

        window.onload = function () {
            var list = document.getElementsByClassName('list')
            for (var i = 0; i < list.length; i++) {
                (function (i) {
                    list[i].addEventListener('click', function () {
                        alert(i);
                    })
                })(i)
            }
        }      

首先将每次绑定都改为立即执行函数,其次将i作为变量传入IIFE,这样for循环对i的更新将不会影响IIFE内的i。
除了这样修改,还可以用ES6的关键字let的替代var进行i声明,也可以解决这个问题。
第二个问题也迎刃而解,我们知道name的值并没有作为变量传入IIFE,那么if的时候name理所当然是未定义,此时程序走的第一个分支,输出的是Goodbye Jack。
光理解这个输出是不够的,可以试下,将立即执行函数的对name的声明改为let,你会发现,程序居然输出了Hello Tom。
0915

这个地方就有点吊诡了,看了资料分析说,是因为我用let声明的变量,引擎认为在IIFE内是有这个变量的,所以执行的时候会走else,但因为if分支并未执行,所以初始化称jack的操作没有进行,此时系统在本作用域内找不到name,就会逐级向上找,一直找到window,然后就找到了Tom。
好吧,js引擎是个任性boy,不按常理出牌,他的套路分分钟绕晕我。

相关文章
|
6月前
|
前端开发 JavaScript 开发者
揭秘JavaScript魔法三剑客:call、apply、bind,解锁函数新世界,你的前端之路因它们而精彩!
【8月更文挑战第23天】在 JavaScript 的世界里,`call`、`apply` 和 `bind` 这三个方法常常让新手感到困惑。它们都能改变函数执行时的上下文(即 `this` 的指向),但各有特点:`call` 接受一系列参数并直接调用函数;`apply` 则接收一个参数数组,在处理不确定数量的参数时特别有用;而 `bind` 不会立即执行函数,而是创建一个新版本的函数,其 `this` 上下文已被永久绑定。理解这三个方法能帮助开发者更好地运用函数式编程技巧,提升代码灵活性和可维护性。
56 0
|
4月前
|
前端开发 JavaScript
前端:实现一个 sleep 函数
在前端开发中,实现一个 `sleep` 函数可以用来暂停代码执行,模拟延迟效果,常用于测试或控制异步操作的节奏。该函数通常基于 `Promise` 和 `setTimeout` 实现,简单易用。
|
5月前
|
存储 前端开发 JavaScript
前端基础(十二)_函数高级、全局变量和局部变量、 预解析(变量提升)、函数返回值
本文介绍了JavaScript中作用域的概念,包括全局变量和局部变量的区别,预解析机制(变量提升),以及函数返回值的使用和类型。通过具体示例讲解了变量的作用域、函数的返回值、以及如何通过return关键字从函数中返回数据。
36 1
前端基础(十二)_函数高级、全局变量和局部变量、 预解析(变量提升)、函数返回值
|
5月前
|
存储 前端开发 JavaScript
前端基础(十一)_函数声明及调用、函数的形参与实参、arguments参数、函数的参数类型、函数中的问题
本文介绍了JavaScript中函数的声明及调用、形参与实参的概念、arguments对象的使用、函数参数的类型以及函数中this的作用。通过示例代码详细解释了函数如何接收参数、如何处理参数个数不匹配的情况,以及函数在不同上下文中this的指向。
54 1
|
6月前
|
JSON 前端开发 API
构建前端防腐策略问题之更新getMemoryUsagePercent函数以适应新的API返回格式的问题如何解决
构建前端防腐策略问题之更新getMemoryUsagePercent函数以适应新的API返回格式的问题如何解决
构建前端防腐策略问题之更新getMemoryUsagePercent函数以适应新的API返回格式的问题如何解决
|
5月前
|
JavaScript 前端开发
前端JS函数
【9月更文挑战第4天】前端JS函数
37 6
|
7月前
|
JavaScript 前端开发 NoSQL
前端node如何学习进阶知识
【7月更文挑战第8天】 深化JavaScript基础,精通Node.js核心模块(如fs、http)与事件循环机制,学习Express框架及异步编程(回调、Promise、async/await),掌握数据库交互,参与实战项目,关注Node.js最新技术和最佳实践,以此提升进阶技能。
72 8
|
7月前
|
开发框架 前端开发 JavaScript
循序渐进VUE+Element 前端应用开发(22)--- 简化main.js处理代码,抽取过滤器、全局界面函数、组件注册等处理逻辑到不同的文件中
循序渐进VUE+Element 前端应用开发(22)--- 简化main.js处理代码,抽取过滤器、全局界面函数、组件注册等处理逻辑到不同的文件中
|
7月前
|
开发框架 JSON 前端开发
循序渐进VUE+Element 前端应用开发(7)--- 介绍一些常规的JS处理函数
循序渐进VUE+Element 前端应用开发(7)--- 介绍一些常规的JS处理函数
|
7月前
|
JavaScript 前端开发
前端框架原理自测题:根据 JSX / Vue 模板写出 render 函数 / VNode
前端框架原理自测题:根据 JSX / Vue 模板写出 render 函数 / VNode
36 0

热门文章

最新文章

  • 1
    【Java若依框架】RuoYi-Vue的前端和后端配置步骤和启动步骤
  • 2
    【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
  • 3
    【05】flutter完成注册页面完善样式bug-增加自定义可复用组件widgets-严格规划文件和目录结构-规范入口文件-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
  • 4
    【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
  • 5
    详解智能编码在前端研发的创新应用
  • 6
    巧用通义灵码,提升前端研发效率
  • 7
    【07】flutter完成主页-完成底部菜单栏并且做自定义组件-完整短视频仿抖音上下滑动页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
  • 8
    智能编码在前端研发的创新应用
  • 9
    【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
  • 10
    抛弃node和vscode,如何用记事本开发出一个完整的vue前端项目
  • 1
    以项目登录接口为例-大前端之开发postman请求接口带token的请求测试-前端开发必学之一-如果要学会联调接口而不是纯写静态前端页面-这个是必学-本文以优雅草蜻蜓Q系统API为实践来演示我们如何带token请求接口-优雅草卓伊凡
    24
  • 2
    大前端之前端开发接口测试工具postman的使用方法-简单get接口请求测试的使用方法-简单教学一看就会-以实际例子来说明-优雅草卓伊凡
    43
  • 3
    【2025优雅草开源计划进行中01】-针对web前端开发初学者使用-优雅草科技官网-纯静态页面html+css+JavaScript可直接下载使用-开源-首页为优雅草吴银满工程师原创-优雅草卓伊凡发布
    25
  • 4
    巧用通义灵码,提升前端研发效率
    84
  • 5
    【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
    137
  • 6
    详解智能编码在前端研发的创新应用
    92
  • 7
    智能编码在前端研发的创新应用
    75
  • 8
    【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
    35
  • 9
    【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
    111
  • 10
    【07】flutter完成主页-完成底部菜单栏并且做自定义组件-完整短视频仿抖音上下滑动页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
    73