1.什么是闭包
当一个嵌套的内部(子)函数引用了嵌套外部(父)函数变量时,就产生了闭包
function fn1(){
var a = 2;
var b = 'abc';
function fn2(){ //执行函数定义,就会产生闭包(不用调用内部函数)
console.log(a)
}
// fn2();
}
fn1();
2.产生闭包的条件
函数嵌套
内部函数引用外部函数数据(变量)
3.如何使用闭包
function fn1(){
var a =2;
function fn2(){
a++;
console.log(a);
}
return fn2
}
var f= fn1(); //此时闭包已经产生
f();//3
f();//4
为什么最后一个会是4?因为执行fn1创建了一个闭包,执行f()会执行fn2
1.函数执行完之后,函数内部声明的局部变量是否还在
一般并不会存在,存在于闭包的变量才会存在
2.在函数外部能直接访问到内部函数的局部变量吗
不能,但是可以通过闭包来操作
4.闭包生命周期
1.产生:在嵌套内部函数定义执行完就产生了(不是在调用) 只是创建了内部函数对象
2.死亡:在嵌套的内部函数成为垃圾对象时
5.js闭包可以实现js自定义模块
定义函数模块
function myModule(){
// 私有数据
var msg = 'My world';
// 操作数据的函数
function doSomething(){
console.log('doSomething()'+msg.toUpperCase);
}
function doOtherthing(){
console.log('doOtherthing()'+msg.toLowerCase)
}
// 向外暴露 (给外部暴露使用的方法)
return {
doSomething:doSomething,
doOtherthing:doOtherthing
// 前面是字符串 后面是函数
}
}
var module = myModule();
module.doSomething();
module.doOtherthing();
定义匿名函数模块
(function(window){
// 私有数据
var msg = 'My world';
// 操作数据的函数
function doSomething(){
console.log('doSomething()'+msg.toUpperCase);
}
function doOtherthing(){
console.log('doOtherthing()'+msg.toLowerCase)
}
// 向外暴露对象(给外部使用的方法)
window.myModule ={
doSomething:doSomething,
doOtherthing:doOtherthing
// 前面是字符串 后面是函数
}
})(window)
匿名函数暴露调用更加方便,代码压缩
myModule.doSomething();
myModule.doOtherthing();
5.闭包面试题
// 代码片段一
var name = "The window";
var object = {
name:"My Object",
getNameFunc:function(){
return function(){
return this.name;
};
}
};
alert(object.getNameFunc()());
结果是 The window
为什么因为调用时返回了一个函数,再执行函数,是this是window
// 代码片段二
var name2 = 'The Window';
var object2 = {
name2:"My Object",
getNameFunc:function(){
var that = this;
// 调用getNameFunc就是object2,所以将this保存起来
return function(){
return that.name2;
};
}
};
alert(object2.getNameFunc()());
结果是 my object
此时存在闭包,将object2的this用that保存起来,存在内部函数引用外部函数的变量