理解立刻执行函数(IIFE)的构造原理、运行机制

"立即执行函数(IIFE)是一种在JavaScript中定义并立即执行的函数,通过避免函数声明污染全局变量,实现作用域隔离和私有变量。常见的IIFE写法是使用括号包裹函数,如`(function() { /* 函数体 */ }
摘要由CSDN通过智能技术生成

立刻执行函数Imdiately Invoked Function Expression)到底是什么意思呢?

顾名思义:在该函数定义之后立即被执行的函数。

许多小伙伴应该和我有同样的想法:这不很好操作嘛?操作如下:

function(){
   //函数体
}()
//确实符合先定义-function(){},再调用-后面加()

运行结果:报错!----------->(为啥呢?,先定义函数然后调用......问题出现在哪儿了?)

下面就和大家一起探索一下“function和JavaScript引擎解析”之间的奇妙关系~

function关键字,既可以用作语句,也可以用作表达式。如果不加以区分或限定,代码在解析时,就会“不知所措”,分不清是当作语句,还是当作表达式来处理。为了避免这种歧义的产生,JS引擎规定,如果function关键字出现在一行代码的最前部,一律解析为语句。

看到这里,小伙伴应该已经明白上述代码块的报错原因了,可以看到function关键字位于行首,所以JS引擎直接将其当作语句处理,误认为只是函数定义,并不会对此函数产生调用行为。

分不清函数语句和函数表达式的童靴,可以看我的另一篇CSDN博客:

解决方法:

可以用一对括号将整个函数包裹起来,这样function就不在行首了,JS引擎会将其解析为表达式。

括号的使用方法有两种:

//第一种方法,用括号将函数的定义部分包裹起来,再进行调用
(function(){
    console.log('于臭臭需要于香香');
})()

//第二种方法,用括号将函数的定义和调用都包裹起来
(function(
    console.log('于香香需要于臭臭');
){}())

那么除了用圆括号包裹的形式,能不能用其他符号代替呢?答案是:可以。

//行首添加~符号
~function(){
    //函数体
}();

//行首添加+符号
+function(){
    //函数体
}();

除了上面显示的两个方式外,还有很多方式,但是作用的原理都是一样的,即:避免function出现在行首,要将function(){]转化为一个可以执行的表达式。虽然有众多的写法,但是用圆括号包裹的方法更加常见,也比较推荐。因为会让代码整体看来更加清晰、整洁。

立即执行函数的用途:

1. “环保性”:从此函数的声明和调用可以看出,我们不需要为函数命名,避免污染全局变量。

2. “私有性”:内部可以形成独立的作用域,将一些变量转化为私有变量,令外部无法访问。

思考题

请尝试运行以下代码,运行结果和你想象中的一样嘛?原因是什么呢?

<ul id="flist">
    <li>苹果</li>
    <li>香蕉</li>
    <li>榴莲</li>
    <li>火龙果</li>
    <li>荔枝</li>
</ul>
<script>
    var ul=document.getElementById("flist")
    var list = ul.getElementsByTagName('li');
    for (var i=0; i<list.length; i++){
        list[i].onclick = function (){
            alert(i); //打印出来的i是多少呢?
        }
    }
</script>

运行结果:5   应该有很多人认为结果应该是0,1,2,3,4

原因解释:i变量是作用于全局范围,并不是for循环每次执行都能得到一个独立的i变量,并没有和每次点击事件进行绑定。再考虑用户点击一定是在for循环完成之后进行的,这时变量已经变成5。

解决方法:思路很简单,只要尝试把i变成独立的变量,每次循环都能创建一个单独的作用域。因此立即执行函数的“私有性”特点能够解决这个问题。代码如下:

        for(var i=0; i<list.length; i++){
            (function (j){
                list[j].onclick = function (){
                    alert(j);
                }
            })(i);
        }

除此之外,还有其他的方法,例如使用ES6的块级作用域。代码如下:

        for(let i=0; i<list.length; i++){
            list[i].onclick = function () {
                alert(i);
            }
        }

|

|

|

|

|

|

于臭臭生活日记——get抓壁虎技能(me-内心期盼壁虎顺利逃出狗爪 ⊙﹏⊙∥)!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值