侧边栏壁纸
博主头像
woku博主等级

成功的路上并不拥挤

  • 累计撰写 50 篇文章
  • 累计创建 13 个标签
  • 累计收到 3 条评论

立即执行函数、闭包深入、逗号运算符

woku
2022-03-07 / 0 评论 / 0 点赞 / 66 阅读 / 1,910 字

先来看一段代码

function test1() {
  console.log('a')
}
function test2() {
  test1()
}
test2() 

在上面的代码中,全局作用域中(GO环境中)有2个函数,会存在这样的现象

  • 2个函数永远不释放
  • 2个函数在任意地方都能执行

而有的时候需求可能是页面加载就执行,并且只执行一次,之后就再也不会执行。既然只执行一次,那么执行这一次之后应该让函数释放。

这样的需求的话,我们写的函数就必须符合

  1. 能自动执行
  2. 执行完之后立即释放

符合上述2点的函数就是我们的立即执行函数

立即执行函数

概念

立即执行函数 (IIFE)Immediately-invoked function expression

也称之为初始化函数,在大多数情况下,被用来做初始化(加载时自动执行)

2个特点:能自动执行、执行完后立即释放

写法

(function heiyg() {
    console.log('heiyg')
})()
(function heiyg(){
    console.log('heiyg')
}())

注意:

  • 只有表达式才能被执行

    function test() {
        console.log('heiyg')
    }
    test()  // 能正常执行
    
    function test() {
        console.log('heiyg')
    }()  // 执行报错
    
    var test =  function() {
        console.log('heiyg')
    }() // 能正常执行
    // 字面量方式声明函数是一个表达式,so能够被执行。
    
    (function(){
        console.log('heiyg')
    })() // 能正常执行
    

    上面的代码片段中,()括起来的就是表达式,只有表达式才能被执行

  • 在表达式中会忽略函数名称

    (function heiyg(){
        console.log('heiyg')
    })()
    console.log(heiyg)
    

    报错:Uncaught ReferenceError: heiyg is not defined

    这样也能从侧面证明函数执行完之后销毁

传参

(function (a,b) {

​ return a + b

}(2,3)

如果立即执行函数return一个值,可以用一个变量来接收返回值

var test = (function (a,b) {

​ return a + b

}(2,3)

<script>
    function heiyg(a) {
        console.log(a)
    }()   // 会报错 必须是表达式才能执行
    function heiyg(a) {
        console.log(a)
    }(6)   // 不会报错,js引擎会把(6)看成一个表达式,函数也并不会执行
</script>
<script>
    if(function b(){}) {
       console.log(10 + typeof(b)
    }
                   
    // 1.判断是否进if语句  true
    // 2.(function b(){})是用()包裹的,那么就是表达式,表达式里面是忽略函数名的,
    //  因此如果console.log(b)会报错,typeof(b)那么就是undefined.最后进行字符串拼接。
    //  打印10undefined
                   
</script>

经典案例

       function test() {
            var arr = []
            for (var i = 0; i < 10; i++) {
                arr[i] = function() {
                    console.log(i)
                }
            }
            return arr
        }

        var t = test()
        for (var i = 0; i < t.length; i++) {
            t[i]()
        }
       // 上面的test函数和下面的等价
       // function test() {
       //      var arr = []
       //      var i = 0;
       //      for (; i < 10;) {
       //          arr[i] = function() {
       //              console.log(i)
       //          }
       //          i++
       //       }
       //      return arr
       //  }

       //  在test()的前一刻,生成AO.执行代码中,arr数组中每一项都是函数,但是函数并没有执行.
       //  函数被定义,作用域链和test的AO一样。
       //  返回arr,此时产生了闭包。当test执行完后,AO的连线剪掉,但AO对象还在,此时i为10
       //  返回的方法执行时打印的i就是10

改进:让函数执行

       function test() {
            var arr = []
            for (var i = 0; i < 10; i++) {
                (function(j) {
                    arr[j] = function() {
                        console.log(j)
                    }
                })(i)
            }
            return arr
        }

        var t = test()
        for (var i = 0; i < t.length; i++) {
            t[i]()
        }

逗号运算符

表达式中的逗号运算返回最后一个值

var n = (3,4,5)
console.log(n) // 5
0

评论区