1. 概念
对其他函数进行操作的函数,其接收函数作为参数/将函数作为返回值输出。
2. 接收函数作为参数:回调函数
3. 将函数作为返回值输出:闭包
1. 什么是闭包
有权访问另一个函数作用域中变量的函数。也即一个作用域可以访问另一个函数内部的局部变量,而被访问的局部变量所在的函数便为闭包。简单的可以认为:闭包就是一种现象,一个作用域可以访问另一个函数内部局部变量的一个现象,也可以认为子函数访问父函数局部变量的一种机制。
2. 闭包的作用
-
延申了变量的作用范围
-
理解:函数中的函数成员可以访问父函数中的局部变量,但是当函数执行完成之后,局部变量一般会被释放掉,但是如果采用闭包,在函数外调用函数中的函数时,由于子函数使用了父函数中的变量,因此暂时不会释放,等待调用。因此在一定程度上延申了变量的作用范围,让其不局限作用于函数中,但是长此以往,也会产生内存泄漏的问题的出现。
-
案例:
function fn() { // 闭包(函数) var num = 1;// 父函数局部变量 return function fun() { console.log(num);// 使用父函数局部变量 } } fn()();// 等价于 fun();
-
使用闭包:立即执行函数(小闭包)
-
循环注册点击事件
<ul class="nav"> <li>好的</li> <li>欧克</li> <li>是的</li> <ul> var lis = document.querySelector('.nav').querySelectorAll('li'); for (var i = 0; i < lis.length; i++) { // 为每个li标签添加立即执行函数,并传递当前的索引i (function (i) { lis[i].onclick = function () { console.log(i); } })(i); // 每一次的执行类似于: //(function(0) { // lis[0].onclick = function() { // console.log(0); // } // })(0); // 当事件发生的时候,便于采取闭包思路,获取父函数(立即执行函数中的局部变量i的值),直接进行打印操作 }
-
闭包中的this指向
-
第一种情形:没有使用闭包
uname = 'OutThing';// 作为window属性存在 var ob = { uname: "Myob", myFun: function () { return function () { return this.uname; } } } console.log(ob.myFun()());// OutThing // 等价于 // var f = ob.myFun(); // var fn = f(); // fn = function () { // return this.uname; // }(); // 所以当前的this指向的是window,因此结果为OutThing
-
第二种情形:使用了闭包
-
uname = 'OutThing';// 作为window属性存在 var ob = { uname: "Myob", myFun: function () { var that = this;// 指向函数调用者 return function () { return that.uname; } } } console.log(ob.myFun()());// Myob // 等价于 // var f = ob.myFun(); // var fn = f(); // fn = function () { // return that.uname; // 而that作为父函数局部变量,值为指向的函数调用者,也即ob对象,因此结果为Myob // }();
-