Appearance
一、理解闭包
- 闭包如何产生
- 当一个嵌套的内部函数引用了嵌套的外部函数的变量时,就产生了闭包。
- 闭包是什么
- 闭包是嵌套的内部函数
- 包含被引用变量的对象,闭包存在于嵌套的内部函数中。
- 闭包产生的条件
- 嵌套函数
- 内部函数引用外部函数的数据
- 示例:javascript
function fn1 () { var b = '123' var a = 2 function fn2 () { console.log(a) } fn2(); } fn1();
二、常见的闭包
- 将函数作为另一个函数返回值JavaScript
function fn1 () { var a = 2 function fn2 () { a++ console.log(a) } return fn2 } var f = fn1() f() f() - 将函数作为实参传递给另一个函数调用JavaScript
function showDelay(msg,time){ setTimeout(function (){ alert(msg) },time) } showDelay('1231232',2000)
三、闭包的作用
1. 函数内部的变量,在函数执行结束后,仍然存活在内存中,延长了局部变量的声明周期
2. 让函数外部可以操作到函数内部的数据(变量/函数)
四、闭包的生命周期
- 产生:在嵌套内部函数定义执行完成时产生(不是在调用产生)
- 死亡:在嵌套的内部函数成为垃圾对象时,闭包死亡,释放占用的内存。js
function fn1 () { // 此时闭包产生了(函数提升,内部函数对象已经创建了) var a = 2 function fn2 () { a++ console.log(a) } return fn2 } var f = fn1() f() // f() // f = null // 闭包死亡(包含闭包的函数对象,成为了垃圾对象)
五、闭包的应用:自定义js模块
具有特定的js文件,将所有的数据和功能封装在一个函数内部(私有的),值向外暴露一个包含n个对象或者函数,模块的使用者,只需要通过模块暴露的对象调用方法来实现对应功能。
- 示例
js
<body>
<script src='myModule.js'></script>
<script>
var module = myModule();
module.doSomething();
module.doOtherIng();
</script>
</body>js
function myModule() {
// 私有数据
var msg = 'Soul Mate'
// 操作数据的函数
function doSomething() {
console.log('do something', msg.toUpperCase())
}
function doOtherIng() {
console.log('doOtherIng'+msg.toLowerCase())
}
// 向外暴露对象(给外部使用的方法)
return {
doSomething: doSomething,
doOtherIng: doOtherIng
}
}- 另一种写法
js
<body>
<script src="myModule2.js"></script>
<script>
myModule2.doSomething();
myModule2.doOtherthing();
</script>
</body>js
(function myModule(window) {
// 私有数据
var msg = 'Soul Mate'
// 操作数据的函数
function doSomething() {
console.log('do something', msg.toUpperCase())
}
function doOtherIng() {
console.log('doOtherIng'+msg.toLowerCase())
}
// 向外暴露对象(给外部使用的方法)
window.myModule2 = {
doSomething: doSomething,
doOtherIng: doOtherIng
}
})(window)六、闭包的缺点及解决
- 缺点:函数执行后,函数内的局部变量没有释放,占用内存时间边长,容易造成内存泄漏
- 解决:及时释放。变成垃圾对象进行释放
js
function fn1(){
var arr = new Array[10000]
function fn2(){
console.log(arr.length)
}
return fn2
}
var f = fn1();
f();
f = null;//让内部函数成为垃圾对象,从而回收闭包对象七、内存溢出和内存泄漏
- 内存溢出:一种程序运行错误,当程序运行时,需要的内存超过了剩余内存,就会抛出内存溢出的错误。
- 内存泄漏:占用内存没有及时释放,内存泄漏积累多了就容易造成内存溢出。
- 常见的内存泄漏:1.意外的全局变量。2.没有及时清理的计时器或回调函数。3.闭包
js
// 内存泄漏
// 意外的全局变量
function fn() {
a = 3
console.log(a);
}
fn();
// 没有及时清理的计时器或回调函数
var intervalId = setInterval(function () {//自动循环定时器不清理
console.log('12312312312')
},1000)
clearInterval(intervalId)八、小练习
js
var name = 'soul mate';
var object = {
name:'my object',
getNameFunc : function () {
return function () {
return this.name;
}
}
}
alert(object.getNameFunc()());//soul mate
var name2 = 'the window'
var object2 = {
name2:'my Object',
getNameFunc: function(){
var that = this;
return function(){
return that.name2
}
}
}
alert(object2.getNameFunc()())//my object