7.1立即执行函数
IIFE immediately-invoked fuction expression
立即执行函数功能化称呼-初始化函数
特点
- 自动执行
- 执行完成以后立即释放
两种写法
(function(){
})();
(function(){
}());//W3C
传实参方式
(function(a, b){
console.log(a + b);
}(2, 4));//6
可传递返回值
var num = (function(a, b){
return a + b;
}(2, 4));
区分
()包起来的为表达式 ->函数名被自动忽略
一定是表达式才能被执行符号执行
function test(){
}();//报错
var test = function(){
console.log(1);
}();//1
(function test(){
console.log(1);
})();//1
var test = function(){
console.log(1);
}
console.log(test);
var test = (function(){
console.log(2);
})()
console.log(test);
函数变表达式,可立即执行
+function test(){
console.log(1);
}();//1
0 || function test(){
console.log(1);
}();//1
1 && function test(){
console.log(1);
}();//1
function test(a){
console.log(1);
}(6);
7.2逗号运算
只返回最后一个
var num = (2 - 1, 6, 24 + 1);
console.log(num);//25
7.3面试题
闭包深入
function test(){
var arr = [];
for(var i = 0; i < 10; i++){
arr[i] = function(){
document.write(i + '');
}
}
return arr;
}
var myArr = test();
console.log(myArr);
function test(){
var arr = [];
for(var i = 0; i < 10; i++){
arr[i] = function(){
document.write(i + '');
}
}
return arr;
}
for(var j = 0; j < 10; j++){
myArr[j]();
}
function test(){
var arr = [];
var i = 0
for(; i < 10;){
arr[i] = function(){
document.write(i + '');
}
i++
}
return arr;
}
var myArr = test();
for(var j = 0; j < 10; j++){
myArr[j]();
}
为什么是10个10?
- var i = 0
- 判断 i < 10
- 声明了arr[0]-arr[9]
- i =10
- return arr 将arr[0]-arr[9]赋给myArr
- arr[0]-arr[9]执行
修改
- 改成立即执行函数
function test(){
var arr = [];
for(var i = 0; i < 10; i++){
(arr[i] = function(){
document.write(i + '');
})();
}
return arr;
}
var myArr = test();
for(var j = 0; j < 10; j++){
myArr[j]();
}
在test()函数体外传入实参
function test(){
var arr = [];
for(var i = 0; i < 10; i++){
arr[i] = function(num){
document.write(num + '');
}
}
return arr;
}
var myArr = test();
for(var j = 0; j < 10; j++){
myArr[j](j);
}
在test()函数体内传入实参
function test(){
var arr = [];
for(var i = 0; i < 10; i++){
(function(j){
arr[i] = function(){
document.write(j + '');
}
})(i);
}
}
return arr;
}
for(var j = 0; j < 10; j++){
myArr[j]();
}
面试题
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
<script type="text/javascript">
var oLi = document.querySelectorAll('li');
for(var i = 0; i < oLi.length; i++){
oLi[i].onclick = function(){
console.log(i);
}
}
</script>
<script type="text/javascript">
var oLi = document.querySelectorAll('li');
for(var i = 0; i < oLi.length; i++){
oLi[j].onclick = function(){
console.log(j);
}//5
</script>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
<script type="text/javascript">
var oLi = document.querySelectorAll('li');
for(var i = 0; i < oLi.length; i++){
oLi[i].onclick = function(){
console.log(i);
}
}
</script>
<script type="text/javascript">
var oLi = document.querySelectorAll('li');
for(var i = 0; i < oLi.length; i++){
(function(j){
oLi[j].onclick = function(){
console.log(j);
}
})(i)
}
</script>
逗号函数
var fn = (
function test1(){
return 1;
},
function test2(){
return '2';
}
)();
console.log(typeof(fn));//string
细节
var a = 10;
if(function b(){}){
a += typeof(b);
}
console.log(a);
应用
累加器 (用闭包);
function acc(){
var num = 0;
function add(){
console.log(++num);
}
return add;
}
var fn = acc();
fn();
一个班级,学生姓名保存在一个数组里,两个方法写在函数中的一个对象中,第一个方法加入班级,第二个方法离开班级,每次加入或离开,都需要打印新的学生名单
方法一
function myClass(){
var students = [];
var operations = {
join : function(name){
students.push(name);
console.log(students);
},
leave : function(name){
for(var i = 0;i < students.length; i++){
var item = students[i];//提高性能
if(item === name){
students.splice(i, 1);
}
}
console.log(students);
}
}
return operations;
}
var obj = myClass();
obj.join('张三');
obj.join('李四');
obj.join('王五');
obj.leave('李四');
方法二
function myClass(){
var students = [];
var operations = {
join : function(name){
students.push(name);
console.log(students);
},
leave : function(name){
var idx = students.indexOf(name);
if(idx !== -1){
students.splice(idx, 1);
}
console.log(students);
}
}
return operations;
}
var obj = myClass();
obj.join('张三');
obj.join('李四');
obj.join('王五');
obj.leave('李四');