-
前言
面试官在面试前端的时候基本都会问到什么是是闭包,因为闭包会涉及到垃圾的回收机制,作用域及作用域链。这里我发表一下本人对闭包的理解,也希望大佬们给到我指点以及纠正。
-
什么是闭包
本人在JavaScript高级程序设计(第四版)“红宝书”上面看到是这么描述闭包的:闭包指的是那些引用了另一个函数作用域中变量的函数。
这句话是什么意思呢:简单来说就是函数A用到了B函数中的变量,那么函数A就是个闭包,其实闭包就是个函数。
我们看一下代码示例
// 声明一个名为B的函数
function B() {
var b = 2
function A() {
console.log(b); //函数A访问了函数B里面的变量
}
}
此时A( )函数就是一个闭包函数,看到这里想必小伙伴们都知道什么是闭包了吧
// 声明一个名为B的函数
function B() {
var b = 2
function A() {
console.log(b); //函数A访问了函数B里面的变量
}
}
B() //调用函数
console.log(b); //B函数外部输出b的值 => b is not defined
直接奖励了一个报错 b is not defined 代码写了多的小伙伴肯定知道这样是不行的,到底为什么不行呢,这里就涉及到了JS的垃圾回收机制
2.垃圾回收机制:(浅谈)
JS代码在运行时会每隔一段时间来回收掉那些没有在用的变量,并且释放其所占用的内存,简单来说就是为了防内存泄漏。
垃圾的回收机制主要有两种方法《标记清除》和《引用计数》
这里我们简单的说一下《标记清除》的方法。下面的执行环境大家可以理解为执行上下或作用域。
就拿上面的代码来说,当JS代码在执行时,首先会进入全局执行环境,当代码调用函数B时,代码就会进入B函数执行环境。此时会标记B函数内部的变量b为“进入环境”。当B函数代码执行完毕后,会退出B函数的执行环境,则将B函数内部的变量b标记为“离开环境”。被标记“离开环境”的变量就会被回收掉内存。
综上所述就可以知道为什么会报错了,因为函数内部的变量已经被销毁掉了。
3.我们再想想怎么才能外部使用函数内部的变量?这里就可以应用到闭包的知识点了
示例代码
// 声明一个名为B的函数
function B() {
var b = 2
return function A() {
return b
}
}
var ser = B()
console.log(ser()); //此时返回的是一个2