死亡: 嵌套的内部函数成为垃圾对象时。(比如f = null,就可以让f成为垃圾对象。意思是,此时f不再引用闭包这个对象了)
闭包的应用:定义具有特定功能的js模块将所有的数据和功能都封装在一个函数内部(私有的),只向外暴露一个包含n个方法的对象或函数。
模块的使用者, 只需要通过模块暴露的对象调用方法来实现对应的功能。
方式一(1)myModule.js:(定义一个模块,向外暴露多个函数,供外界调用)
functionmyModule() {
//私有数据
var msg = 'Smyhvae Haha'
//操作私有数据的函数
functiondoSomething() {
console.log('doSomething() ' + msg.toUpperCase()); //字符串大写
}
functiondoOtherthing() {
console.log('doOtherthing() ' + msg.toLowerCase()) //字符串小写
}
//通过【对象字面量】的形式进行包裹,向外暴露多个函数
return {
doSomething1: doSomething,
doOtherthing2: doOtherthing
}
}
上方代码中,外界可以通过doSomething1和doOtherthing2来操作里面的数据,但不让外界看到。
(2)index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>05_闭包的应用_自定义JS模块</title>
</head>
<body>
<!--闭包的应用 : 定义JS模块 * 具有特定功能的js文件 * 将所有的数据和功能都封装在一个函数内部(私有的) * 【重要】只向外暴露一个包含n个方法的对象或函数 * 模块的使用者, 只需要通过模块暴露的对象调用方法来实现对应的功能-->
<script type="text/javascript" src="https://www.linuxidc.com/myModule.js"></script>
<script type="text/javascript">var module =myModule();module.doSomething1();module.doOtherthing2();</script>
</body>
</html>
同样是实现方式一种的功能,这里我们采取另外一种方式。
(1)myModule2.js:(是一个立即执行的匿名函数)
(function () {
//私有数据
var msg = 'Smyhvae Haha'
//操作私有数据的函数
functiondoSomething() {
console.log('doSomething() ' + msg.toUpperCase())
}
functiondoOtherthing() {
console.log('doOtherthing() ' + msg.toLowerCase())
}
//外部函数是即使运行的匿名函数,我们可以把两个方法直接传给window对象
window.myModule = {
doSomething1: doSomething,
doOtherthing2: doOtherthing
}
})()
(2)index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>05_闭包的应用_自定义JS模块2</title>
</head>
<body>
<!--闭包的应用2 : 定义JS模块 * 具有特定功能的js文件 * 将所有的数据和功能都封装在一个函数内部(私有的) * 只向外暴露一个包信n个方法的对象或函数 * 模块的使用者, 只需要通过模块暴露的对象调用方法来实现对应的功能-->
<!--引入myModule文件-->
<script type="text/javascript" src="https://www.linuxidc.com/myModule2.js"></script>
<script type="text/javascript">myModule.doSomething1()
myModule.doOtherthing2()
</script>
</body>
</html>
上方两个文件中,我们在myModule2.js里直接把两个方法直接传递给window对象了。于是,在index.html中引入这个js文件后,会立即执行里面的匿名函数。在index.html中把myModule直接拿来用即可。
总结:
当然,方式一和方式二对比后,我们更建议采用方式二,因为很方便。
但无论如何,两种方式都采用了闭包。
闭包的缺点及解决缺点:函数执行完后, 函数内的局部变量没有释放,占用内存时间会变长,容易造成内存泄露。
解决:能不用闭包就不用,及时释放。比如:
f = null; // 让内部函数成为垃圾对象 -->回收闭包
总而言之,你需要它,就是优点;你不需要它,就成了缺点。
内存泄漏内存溢出 内存泄漏内存泄漏:占用的内存没有及时释放。内存泄露积累多了就容易导致内存溢出。
常见的内存泄露:
1.意外的全局变量
2.没有及时清理的计时器或回调函数
3.闭包
情况1举例:
// 意外的全局变量
functionfn() {
a = new Array(10000000);
console.log(a);
}
fn();
情况2举例: