1,闭包的理解
1)当一个嵌套的内部(子)函数引用了嵌套的外部(父)函数的变量(函数)时, 就产生了闭包
2,闭包产生的条件
1)函数嵌套
2)内部函数引用了外部函数的数据(变量/函数)
3,闭包的特性
1)内部变量使用完还一直存在,不被垃圾机制回收
4,常见的闭包
1)将函数作为另一个函数的返回值
function fn1() {
var a = 2
function fn2() {
a++
console.log(a)
}
return fn2
}
var f = fn1()
f() // 3
f() // 4
2)将函数作为实参传递给另一个函数调用
function showMsgDelay(msg, time) {
setTimeout(function () {
console.log(msg)
}, time)
}
showMsgDelay('hello', 1000)
5,闭包的使用场景
一般用于自定义js模块,封装功能模块
* 具有特定功能的js文件
* 将所有的数据和功能都封装在一个函数内部(私有的)
* 只向外暴露一个包信n个方法的对象或函数
* 模块的使用者, 只需要通过模块暴露的对象调用方法来实现对应的功能
1)直接返回函数
/**
* 自定义模块1
*/
function coolModule() {
//私有的数据
var msg = 'abc'
var names = ['a', 'b', 'c']
//私有的操作数据的函数
function doSomething() {
console.log(msg.toUpperCase())
}
function doOtherthing() {
console.log(names.join(' '))
}
//向外暴露包含多个方法的对象
return {
doSomething: doSomething,
doOtherthing: doOtherthing
}
}
使用方法
var module = coolModule()
module.doSomething() //ABC
module.doOtherthing() //a b c
2)讲函数暴露给window
/**
* 自定义模块2
*/
(function (window) {
//私有的数据
var msg = 'abc'
var names = ['a', 'b', 'c']
//操作数据的函数
function a() {
console.log(msg.toUpperCase())
}
function b() {
console.log(names.join(' '))
}
window.coolModule2 = {
doSomething: a,
doOtherthing: b
}
})(window)
使用方法
coolModule2.doSomething() //ABC
coolModule2.doOtherthing() //a b c
6,注意事项
1) 函数执行完后, 函数内的局部变量没有释放, 占用内存时间会变长
2)容易造成内存泄露
7,解决方法
1)尽量不使用
2)及时释放,fn = null