-
概念
- 就是能够读取外部函数内部变量的函数;
-
满足条件
- 要访问所在的作用域
- 函数嵌套
- 在作用域之外被调用
-
优点
- 延长变量的生命周期
- 避免全局变量污染
- 在作用域外可以调用函数内私有变量
-
缺点
- 闭包作用域内会有很多变量,会占很大内存,影响网页性能。
- 在IE浏览器会造成内存泄漏
- 解决办法:退出函数之前将不使用的局部变量删除;
-
注意
- 内存泄漏(Memory Leak)是指程序中已动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果
- 闭包在函数外部改变函数内部的值
-
简单实例
-
<script> function loop(){ let num=520 obj={ n:200, fun:function(){return num}, fun1:function(val){num=val;return num} } // 返回值 return obj } let res=loop(); console.log(res.fun1(250)); console.log(res.n); console.log(res.fun()); </script>
-
结果
-
-
闭包语法糖
- 使用getter获取器和setter设置器语法
- 语法
-
get a(){}, set a(val){},
-
- 案例
-
<script> function loop(){ let num=100; obj={ //获取函数 get a(){return num}, // 设置函数 set a(val){num=val} } return obj } let res=loop(); console.log(res.a); res.a=45; console.log(res.a); </script>
- 结果
-
-
闭包之柯理化形式
- 当输入参数时,不再是一次输入所有参数,而是分为一次或者多次输入,这时采用柯理化形式。
- 简单案例
- 实现两个数值累加
-
// 两位数求和 function curry(init){ return function nn(aa){ return aa+init } } let res=curry(10)(85); let a = curry(10)(90); let a1 = curry(20)(70); let a2 = curry(30)(50) ; console.log(res); console.log(a); console.log(a1); console.log(a2); </script>
- 结果
- 复杂案例
- 实现字符串拼接地址栏http://localhost:8080/a
-
<script> function pinjie(a,b,c,d){ return a + '://' + b + ':' + c + '/' + d } // 封装 function currying(fn,...arr){ // 获取fn函数参数 let len=fn.length; // 变量存储参数 let _arr=arr||[] return function(...arr2){ // 功能函数 // 使用展开合并运算符存储变量 _arr=[..._arr,...arr2]; if(_arr.length<len){ // 参数不够时 // 继续获取参数 return currying(fn,..._arr) }else{ // 参数够了 return fn(..._arr) } } } // 调用 let res =currying(pinjie,'http')('127.0.0.1', '8888', '/index.html'); console.log(res); </script>
-
结果
-