前端菜鸟的成长之路
本着要学就要尽量学透彻一点的精神,今天再看看立即执行函数。
立即执行函数模式被广泛使用,它可以帮你封装大量的工作而不会在背后遗留任何全局变量。你定义的所有变量都会成为立即执行函数的局部变量,所以你不用担心这些临时变量会污染全局空间。
(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。