概念 : 能够访问到 其他函数作用域中的对象的函数,称之为闭包。

常用 : 1. 回调函数 2.自调用函数 封装的私有方法 3.防抖 和 节流函数

回调函数 :

通常在 请求结束 拿到返回值的时候 使用 闭包。

function fun(success){
				let returnData = { code : 200, msg : "success" , data : {} }
				success(returnData)
			}
			fun(function (value) {
				console.log(value)
			})
此时 可以拿到 fun函数中的 returnData 值。

自调用函数 :

(如)单例模式 其中对象中的函数 就是闭包 add() value() 闭包的应用

var Counter = (function(){
				var a = 10;
				function changeBy(value){
					a += value
				}
				return {
					add : function(){
						return changeBy(1)
					},
					value : function(){
						return a;
					}
				}
			})();

防抖 节流 :

/* 
			3.防抖 和 节流函数 
			 */
			//防抖
			function fd(fun,time){
				let timer = null;
				return function(){
					if(timer !== null){
						clearTimeout(timer)
					}
					timer = setTimeout(fun,time)
				}
			}
			/* 节流 */
			function jl(fun,time){
				let timer = null;
				return function(){
					if(timer !== null){
						return 
					}
					timer = setTimeout(function(){
						fun()
						timer = null
					},time)
				}
			}

练习题目:

// 面试题
			function fn(){
				var arr = []
				for(var i = 0; i <10; i++){
					arr[i] = function(){
						return i
					}
				}
				return arr
			}
			var arr = fn()
console.log(arr[0]())

题目 : console.log(arr[0]())的值?(答案 : 10)

解析 : arr中存储的 都是函数function(){ return i } 在 console 执行时 此时,因为 for中没有块作用域 a 的 值 等于 10。所有 等于 10

题目 2 : 如何 让 arr[0]() = 0 、 arr[1]() =1 …….

解析 :可以通过 闭包来实现 将 i 私有化

// 当 使用闭包  解决 (自调用函数 将i私有化)
			function fnBb(){
				var arr = []
				for(var i = 0; i <10; i++){
					// 通过 闭包(自调用函数)  来解决  作用域问题
					(function(i){
						arr[i] = function(){
							return i
						}
					})(i)
				}
				return arr
			}

闭包的弊端:

内存泄漏 : 闭包的链表已经创建,每一个闭包作用域携带一个指向大数组的间接的引用,造成严重的内存泄露。

解决方法 :

  1. 尽可能 不用
  2. 使用箭头函数 来控制 this指向
  3. let _this = this
  4. 手动 清空 null

作者 译文

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注