IIFE(自执行函数)
IIFE
(Immediately Invoked function Expression
),立即调用的函数表达式。声明这个函数的同时立即调用这个函数。
所谓自执行函数,顾名思义,就是定义以后就立刻执行的函数,一般没有名字,而且只会执行一次。
//以function开头了那就是需要一个名字,它就不是表达式方式声明。
function (){//这里报的错是:函数需要一个名字。
console.log('foo');
}();
我们常用的就是下面这两种方式:
(function xiaoGuaiGuai(){
console.log('foo!!!');
}());
//这种方式是最常用的。
(function(){
console.log('foo@@@');
})();
小括号的作用:
-
分组操作符。(将数据分成一组)
(1+2)*3
-
函数调用符:前面的东西能够得到一个函数值的时候。
立即调用的函数表达式只能运行一次。原因:确实它还是引用类型,但是没有标识,执行完成之后就被垃圾回收机制回收了。
定义之后马上调用,调用之后马上释放。
即使是两个代码完全相同的IIFE函数,也是不同的执行环境、不同的函数。
IIFE函数本身不会被提升,但是函数内部的代码该提升还是会提升的。
如果要向IIFE中传值那么只需要在函数调用符的地方传入实参:
(function(name){
console.log(name+'是英俊哥!');
})('图图的爸爸');
用处(了解一下):
- 在项目中进行项目的初始化,一进入到程序就对项目进行一系列的初始化,初始化完毕以后就不用了那就释放了。
- 框架、模块、库中使用IIFE的也比较多。因为这样可以用来进行项目的初始化并且只暴露需要暴露的模块。
函数的递归调用
函数的使用方式
- 主角始终都是小军军。
- 小军军一件事没做完就去做另外一件事了。
- 小美女的出现最终实际上是个终止条件(
滚
) - 当前这件事做完之后就会去做上一次还没做完的事。一直到所有的事情都做完。
同一个函数多次调用,执行环境不同(分配的地址空间不同),每个执行环境中的相同的变量没有关系。
递:进去
归:出来
注意:
- 你自己就是这个函数,是你自己调用自己。当自己做完一件现在的事的时候,会去做上次没做完的事。
- 递归一定要有一个条件限制,否则会陷入自己调用自己的旋窝中,永不翻身。
- 不确定具体调用多少次的情况。
例子:
-
求1~5的和,用递归。
编码过程中能少用全局变量就少用全局变量。
-
计算数组中元素的个数。
判断数组:
Array.isArray(变量)
,是数组返回true
,否则返回false
。var arr = [1, [5, 4, 6], 9, [4, 5, [0, 2, [7, 3]]]]; function ARR(arr) { var sum = 0; for (var i = 0; i < arr.length; i++) { if (Array.isArray(arr[i])) { sum += ARR(arr[i]); } else { sum++; } } return sum; } console.log(ARR(arr));
函数的回调(回调函数)
回调函数的精髓:函数是对象,是值,可以被当作参数传入到函数中 。
学习回调函数需要掌握的知识点:
-
将一个引用类型赋值给一个变量时,变量存储的是引用类型的地址。
一个引用类型可以有多个名字,一个改变引用类型的值,另外一个的值也改变。
var a = []; a[0] = '苹果'; var b = a;//a和b的地址指向同一个。 console.log(b); function foo(){ } var foo1 = foo;//也是同一个。
-
函数的参数,如果是普通类型传递的是值,引用类型传递的是地址。
function test(arr){//arr=0x123 arr[arr.length] = '小香蕉'; } var a = ['小苹果'];//0x123 test(a);//test(0x123) console.log(a);//['小苹果', '小香蕉']
-
一个函数本身是值,也是一个对象,可以被当作实参传入到函数中。
-
一个函数本身是值,也是一个对象,所以可以被当作返回值返回回来。
function foo(){//0x123 function bar(){//0x234 console.log('foo---->bar'); } return bar;//0x234 } var res = foo();//res=0x234 res();//0x234()
什么是回调函数
回调函数被认为是一种高级函数,一种被作为参数传入给另外一个函数(A)的高级函数。回调函数会在A里面被调用被执行。
回调函数的本质是一种模式,是解决问题的一种套路。
回调函数的用处
- 事件监听和处理。
- 设置超时和时间间隔。
- Ajax。
- 框架中的各种生命周期回调函数。
- 通用化:代码简洁,易于扩展。
<script>
//通用函数
function getNumber(num, fn) {//num=3;fn=0x123
/*
i=1 1<=3 true
fn(1);//false
console.log(1);
i=2 2<=3 true
fn(2);//true
i=3 3<=3 true
fn(3);//false
console.log(3);
i=4 4<=3 false
*/
for (var i = 1; i <= num; i++) {
if (fn(i)) {
continue;
}
console.log(i);
}
}
//规则1:偶数
function rules1(n) {//0x123
if (n % 2 == 0) {
return true;
} else {
return false;
}
}
// getNumber(3,rules1);//getNumber(3,rules1)
//规则2:和4取余为0的都保留
function rules2(n){
if (n%4!=0){
return true;
}else {
return false;
}
}
// getNumber(10,rules2);
//手抄10遍意思一下。
//规则3:将奇数去掉
getNumber(10,function(n){
if (n % 2 == 0){
return false;
} else{
return true;
}
});
</script>
这个例子你可以看出来将功能提取出来后将各种规则也提取出来,减少耦合、容易扩展。