闭包的由来
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>闭包</title>
</head>
<script>
/**
* 闭包的产生?
* 当一个嵌套的内部函数引用嵌套的外部函数的变量,就产生了闭包
* 闭包是什么?
* 闭包是嵌套的内部函数(大多数人 这么认为)
* 包含被引用变量(函数)的对象(极少数人 这么认为)
* 注意:闭包存在于嵌套的内部函数中
* 产生闭包的条件?
* 函数嵌套,内部函数引用外部函数的数据(变量/函数)并且外部函数执行
*/
/**
* 作用?
* 1. 让函数内部的变量在函数执行完后,仍然存活于内存中(延长局部变量的使用周期)
* 2. 让函数外部可以操作到函数内部的数据(变量/函数)
*
* 闭包的生命周期
* 产生:在嵌套内部函数定义执行完成时就产生了 不用等到调用
* 死亡:嵌套的内部函数成为垃圾对象时
*/
function fun() {
var a = 2
function fun1() {
console.log(a);
}
fun1()
}
fun();
console.log("---------------------");
// 作用
function f1() {
// 闭包产生
var c = 2
function f2() {
c++
console.log(c);
}
function f3() {
c--
console.log(c);
}
return f3
}
var f = f1()
f() // 1
f() // 0
//如果没有引用 直接f1() 闭包就不存在了
// 闭包死亡
f = null
</script>
<body>
</body>
</html>
闭包的应用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>应用</title>
</head>
<!--引用js-->
<script src="Module.js"></script>
<script src="Module2.js"></script>
<script>
/**
* 闭包的应用 : 定义JS模块
* 具有特定功能的js模块
* 将所有的数据和功能都封装在一个函数内部
* 只向外暴露一个包含n个方法的对象或函数(通过return 进行向外暴露,匿名函数通过window进行暴露)
* 模块的使用者,只需要通过模块暴露出来的对象调用方法来实现对应的功能
*/
//引用向外暴露的对象 通过对象引用其中的方法 第一种
var module = Module();
module.m1()
module.m2()
//第二种方式的使用 推荐使用第二种
Moudle2.m1()
Moudle2.m2()
</script>
<body>
</body>
</html>
闭包应用的外部js
//Module.js
function Module() {
//私有数据
var msg = "aa bb cc"
function m1() {
console.log("我是m1"+msg);
}
function m2() {
console.log("我是m2"+msg);
}
//向外暴露对象
return {
m1 : m1,
m2 : m2
}
}
//Module2.js
(function (window) {
//私有数据
var msg = "aa bb cc"
function m1() {
console.log("我是m1"+msg);
}
function m2() {
console.log("我是m2"+msg);
}
//向外暴露对象
window.Moudle2 = {
m1 : m1,
m2 : m2
}
})(window) //匿名函数自调用
闭包的缺点
/**
* 缺点:
* 函数执行完成后,函数内的局部变量不能进行释放,占用内存时间变长 资源利用率低
* 容易造成内存泄露
* 解决:
* 尽量不使用闭包
* 及时释放资源
*/
/**
* 内存溢出 与 内存泄露
* 内存溢出
* 一种程序运行出现的错误,当程序运行需要的内存超过了需要的内存大小,就会抛出内存溢出的错误
*
* 内存泄露
* 占用的内存没有及时的释放
* 内存泄露多了累积起来就会导致内存溢出
* 常见内存泄露
* 意外的全局变量
* 闭包
* 没有及时清理的计时器或者回调函数
*/
正在学习中,不足之处,欢迎指正