前端进阶|第九天 逆天的立即执行函数(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。


image.png

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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,298评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,701评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,078评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,687评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,018评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,410评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,729评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,412评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,124评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,379评论 2 242
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,903评论 1 257
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,268评论 2 251
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,894评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,014评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,770评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,435评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,312评论 2 260

推荐阅读更多精彩内容