零、前言
内容分为以下几点:
·闭包的定义、概念以及特点
·闭包的几种形成方式
·闭包的优缺点以及解决方案
·闭包的应用以及应用场景
一、闭包的定义、概念
1、《JavaScript高级程序设计》这样描述:
闭包是指有权访问另一个函数作用域中的变量的函数;
《JavaScript权威指南》这样描述:
从技术的角度讲,所有的JavaScript函数都是闭包:它们都是对象,它们都关联到作用域链。
《你不知道的JavaScript》这样描述:
当函数可以记住并访问所在的词法作用域时,就产生了闭包,即使函数是在当前词法作用域之外执行。
我觉得应该 理解成最后者 所说的。(“闭包的函数可以记住自己所处的作用域,即记住作用域里面相应变量的值”)
2、特点(函数套函数;函数内部引用外部的 参数、变量从而形成作用域链;参数和变量会留存内存、不被垃圾回收机制所回收)
- 函数嵌套函数。
- 函数内部可以引用外部的参数和变量。
- 参数和变量不会被垃圾回收机制回收。
二、闭包的几种形成方式
1、函数里面定义函数(里面的函数能够访问外面的函数中变量)
function fa(){
let a = '我是a中的变量';
function fb(){
console.log(a); //'我是a中的变量'
}
fb();
}
fa()
2、函数作为 参数传递 进去(回调形式)。
function doSomething(callback){
callback(1,2);
}
function numberAdd(a,b){
document.write(a+b);
}
doSomething(numberAdd);//3
等等。
三、闭包的优缺点以及解决方案
1、闭包的好处(使得某变量长存于内存中、计数啥的?;避免全局变量的污染IIFE、jQuery;生成私有成员、特权函数):
- 希望一个变量长期存储在内存中。
- 避免全局变量的污染。
- 私有成员的存在。
2、闭包的缺点(常驻内存;使用不当会发生内存泄漏):
- 常驻内存,增加内存使用量。
- 使用不当会很容易造成内存泄露。
3、解决内存泄漏问题
举个栗子:
window.onload = function(){
var el = document.getElementById("id");
el.onclick = function(){
alert(el.id);
}
}
解决方案(核心在于将其置为 null ):
window.onload = function(){
var el = document.getElementById("id");
var id = el.id; //解除循环引用
el.onclick = function(){
alert(id);
}
el = null; // 将闭包引用的外部函数中活动对象清除
}
四、闭包的应用以及应用场景
- 私有变量
- 回调与计时器
- 绑定函数上下文
- 偏应用函数
- 函数重载:缓存记忆、函数包装
- 即时函数:独立作用域、简洁代码、循环、类库包装、通过参数限制作用域内的名称