天天看点

JavaScript难点——立即执行函数(二)

前端菜鸟的成长之路

本着要学就要尽量学透彻一点的精神,今天再看看立即执行函数。

立即执行函数模式被广泛使用,它可以帮你封装大量的工作而不会在背后遗留任何全局变量。你定义的所有变量都会成为立即执行函数的局部变量,所以你不用担心这些临时变量会污染全局空间。

(function() {  
    var days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],  
    today = new Date(),  
    msg = 'Today is ' + days[today.getDay()] + ', ' + today.getDate();  
    console.log(msg);  
} ()); 
           

如果代码没有被包裹在立即执行函数中,那么局部变量days,today和msg都将成为全局变量,初始化代码的遗留产物。

立即执行函数的参数

(function(who, when) {  
    console.log("I met " + who + " on " + when);  
} ("Joe Black", new Date()));  
           

立即执行函数的返回值

var result = (function () {  
    return 2 + 2;  
}());  

var result = (function () {  
    return 2 + 2;  
})(); 

var result = function () {  
    return 2 + 2;  
}();  
           

以上代码不必多说,都可以实现将立即执行函数的返回值赋值给一个变量。

需要注意的是,第三种语法可能会给人一点误导,如果没有注意到函数结束的括号,可能就会认为result指向一个函数,实际上result指向立即执行函数的返回值。

立即执行函数能返回任何类型的值,包括其它的函数;

var getResult = (function() {  
    var res =  + ;  
    return function() {  
        return res;  
    };  
} ());  
console.log(getResult); 
//function(){ return res;}
console.log(getResult()); 
//4
           

上例中立即执行函数的返回值是一个函数,被赋值给了变量getResult,这个函数简单的返回了res的值,这个值事先被计算并被储存在立即执行函数的闭包中。

再贴一个经典面试题

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>立即执行函数</title>
    <style>
    li {list-style-type: none;width: px;height: px;text-align: center;line-height: px;background: #07ee33;color: #fff;float: left;margin:  px}
    </style>
</head>
<body>
    <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
        <li>5</li>
        <li>6</li>
    </ul>
    <script>
    var ul = document.getElementsByTagName('ul');
    var liList = ul[].getElementsByTagName('li')
    for (var i = ; i < ; i++) {
        liList[i].onclick = function() {
            alert(i) 
        }
    }
    </script>
</body>
</html>
           

为什么 alert 的总是 6 呢?

我的理解是页面加载完成后, i 的值已经从0加到了6,之后才点击的,此时i值为6。

怎么解决呢?

用立即执行函数给每个 li 创造一个独立作用域即可

for(var i=; i<; i++){
    (function(ii){
        liList[ii].onclick = function(){
            alert(ii) // 0、1、2、3、4、5
        }
    }(i))
}
           

在立即执行函数执行的时候,i 的值被赋值给 ii,i 的值从 0 变化到 5,对应 6 个立即执行函数,这 6 个立即执行函数里面的 ii 「分别」是 0、1、2、3、4、5。

继续阅读