匿名函数,顾名思义是没有函数名称的函数。
我们先创建一个普通函数:
//普通函数
function fn(){
alert("我是普通函数")
}
fn() //调用
我们接着来看匿名函数:
//匿名函数 ,单独的匿名函数无法使用,因为函数调用必须要用到函数名称
function (){
alert("我是匿名函数")
} //报错
我们再来看看匿名函数的调用方法:
情况1.把匿名函数赋值给变量
var fn1 = function(){
alert("我是匿名函数被赋值给变量调用")
}
fn1();//我是匿名函数被赋值给变量调用
情况2.匿名函数自我调用,表达式的方式
(function(){
alert("我是匿名函数通过表达式自我执行")
})();
//我是匿名函数通过表达式自我执行
再来看看匿名函数是如何传递参数的:
匿名函数传递参数,调用方法与上面相同
//1.赋值给变量
var fn2 = function (num1,num2){
alert(num1+num2)
};
fn2(1000,1000);
//2. 自我调用方法
(function(num1,num2){
alert(num1+num2)
})(100,100);
什么是闭包呢?
闭包的概念:
闭包就是有权(访问),(另一个函数作用域)中(变量的函数);
闭包可以简单理解成“定义在一个函数内部的函数“。所以,在本质上,闭包是将函数内部和函数外部连接起来的桥梁。
闭包的作用:
一个是前面提到的可以读取函数内部的变量,
另一个就是让这些变量的值始终保持在内存中,不会在调用后被自动清除。
闭包的概念不太好理解,但是通过一些例子还是很好理解的;
闭包的用途1,读取函数内部的变量
例子1:
function myfun(){
return function (){
return("你用闭包的方式访问到我1")
}
}
alert(myfun); //输出myfun整个函数表达式
alert(myfun()); //输出匿名函数表达式
//闭包调用方式1
alert(myfun()());
//闭包调用方式2
var a = myfun(); //赋值给变量
alert(a())
例子2.通过闭包访问局部变量
function myfun2(){
var a = "你用闭包的方式访问到我2";
return function (){
return a;
}
}
//闭包调用方式1
alert(myfun2()())
//闭包调用方式2
var b = myfun2();
alert(b());
通过上面两个例子相信就大家就能看出来闭包的作用和使用方法。是不是很简单。
闭包的作用2
可以让局部变量始终保持在内存中
例子1:
首先来看简单的累加应用:
var num = 1; //通过全部变量来实现
function add() {
alert(num++)
}
add();//1 每次调用的时候全局变量都会进行++,这样就实现了累加
add();//2
add();//3
我们在局部变量中看下:
function add2(){
var num2 = 1; //局部变量无法实现累加
alert(num2++)
}
add2();
//1由于在局部变量中每次调用都会初始化num2=1,所以就无法实现累加,这种情况下,我们就得使用闭包
add2();//1
add2();//1
通过闭包的方式:
function add3(){
var num3 = 1;
return function (){
num3++;
alert(num3)
}
}
//这种方式并不会实现累加,因为每次调用一次函数,函数都会从上到下执行一次,num都会初始化一次
// add3();//1
// add3();//1
// add3();//1
来看看另一种闭包的调用方式
var fun =add3();
//函数只在赋值的时候初始化一次,接着后面在调用的时候执行的是里面的匿名函数,所以这种方法是可行的。
fun();//2
fun();//3
fun();//4
闭包的优缺点:
优点:可以将局部变量驻留在内存中,可以避免全局变量。
全局变量会在复杂的程序中造成许多麻烦(命名冲突,垃圾回收)
缺点:由于闭包作用域返回的局部变量资源不会被立即销毁回收,
可能会占用更多内存,过度使用闭包会导致性能下降;
所以我们最好在使用完毕之后赋值null
fun=null;