闭包
导航
- 前置知识
- 什么是闭包
- 闭包的用途
- 闭包的缺点
前置知识
-
JavaScript在声明函数或者变量时,会赋予其相应的作用域,有全局作用域,函数作用域以及let/const要注意的的块级作用域
-
示例(1)
//全局作用域
let a =1;
console.log(a); // 1
function b(){
a=2 // 修改了全局变量
}
b();
console.log(a) // 2
- 示例(2)
//块级作用域
let a =1;
console.log(a) // 1
function b(){
let a=2// 局部变量
}
b();
console.log(a) // 1
- 示例(3)
//函数作用域
let a = 1;
console.log(a); // 1
function b() {
let a = 2;
function c() {
a = 3;
}
c()
console.log(a); // 3
}
b();
console.log(a); // 1 全局变量未被污染
一、什么是闭包
-
定义
-
首先看一下百度百科的介绍:闭包就是能够读取其他函数内部变量的函数。例如在javaScript中,只有函数内部子函数才能读取局部变量,所以闭包可以理解成“定义在一个函数内部的函数“。在本质上,闭包是将函数内部和函数外部连接起来的桥梁。
-
所以我们总结一下,并换一种更好理解的方式——闭包就是一个函数引用了另一个函数作用域内的变量
-
-
示例(4)
function check(color) {
let ban1 = 'orange';
let ban2 = 'red';
function noEntry() {
if (color === ban1 || color === ban2) {
console.log('体温不正常')
} else {
console.log('体温正常')
}
}
return noEntry;
}
check('green');
二、闭包的用途
-
根据定义我们可以知道,闭包是在嵌套函数中经常会用到的一种方法。比如示例(4)中,调用变量的函数noEntry被定义在另一个函数check的作用域内。
-
根据下面的例子我们就可以看出闭包的用途
- 1.避免污染全局变量影响后续代码
- 2.可以访问函数内部变量
let a = 1;
console.log(a); // 1
function b() {
let a = 2;
let e = 3;
function c() {
a = 3;
}
c()
console.log(a); // 3
}
b();
console.log(a); // 1 全局变量未被污染
console.log(e); // ReferenceError: e is not defined ; e未定义无法访问函数内部变量
三、闭包的缺点
- 由于闭包会保留它们包含函数的作用域,所以会比其他的函数更占用内存。
- 正常函数作用域会在执行完它的全部代码后释放内存(压栈,弹栈),在一些情况下,闭包的活动对象并不能在它执行完后释放
function a() {
let b = 1;
function c() {
b = 2;
}
c();
return b;
}
a()
let e = a();
console.log(typeof (e)); // number
console.log(e); // 2 变量b的内存没有被释放 供函数C调用