### 闭包
* * * * *
> 在《javascript高级程序设计第三版》中有讲到:“闭包”是指有权访问另一个函数作用域中的变量的“函数”
> 通俗理解:“闭包”就是一个函数,只不过在这个函数内部可以访问到其他函数的作用域中的变量。
##### **这里涉及了很多关于js作用域链的知识,可以先行百度“javascript作用域链”并理解作用域链后再来看,本文只对作用域链做简单介绍**
> 在javascript中,当某个函数被调用时,会创建一个执行环境(execution context)以及与这个执行环境相对应作用域链,使用arguments(***函数的参数对象,function对象默认自带,无需声明,function内部可以调用***)和其他命名参数的值来初始化当前函数的活动对象(activation object),但在作用域链中,外部函数的活动对象始终处于第二位,外部函数的外部函数的活动对象处于第三位...以此类推直至作用域链终点的全局执行环境(***这里有点类似于对象的原型链可以一直向上追溯到object对象***)。
> 接下来,我们一步一步实现一个闭包
~~~
//首先创建一个com函数,这个函数内返回一个匿名函数,匿名函数有两个参数
function com(propertyName){
return function(obj1,obj2){
let value1 = obj1[propertyName]
let value2 = obj2[propertyName]
if(value1 < value2){
return -1
}else if(value1 > value2){
return 1
}else{
return 0
}
}
}
//将com函数赋值给coms,此时的coms变量接收的是com函数return的匿名函数
let coms = com("name")
//然后调用coms函数
let values = coms({name:2},{name:1})
console.log(values) // 此处打印 -1
//接触对匿名函数的引用,以便释放内存,否则容易内存溢出
coms = null
~~~
> 上面例子就是一个典型的闭包案例,因为com返回对匿名函数中包含了com的作用域链,所以可以通过匿名函数来实现引用com作用域内的变量和参数,以达到引用其他函数作用域中的变量的目的!
> ⚠️注意:关于闭包中this的引用,this默认是与执行环境绑定的,在严格模式和非严格模式的闭包中,this的指向也会不同,非严格模式中this指向的是全局对象(如:浏览器中的window),而严格模式中this指向的是当前对象!当然,通过call/apply/bind改变函数执行环境的情况下,this就会指向其他对象!