闭包定义
YDKJS:闭包就是函数能够记住并访问它的词法作用域。(即使当这个函数在它的词法作用域之外执行时)
JavaScript语言精粹:函数可以访问它被创建时所处的上下文环境。
JavaScript高级程序设计:有权访问另一个作用域中变量的函数。
MDN:Closures are functions that refer to independent (free) variables (variables that are used locally, but defined in an enclosing scope). In other words, these functions ‘remember’ the environment in which they were created.
-
闭包特性最重要要区分的就是与词法作用域链特性的区分。词法作用域链特性指的是当前词法作用域可以访问其外部词法作用域。
-
从定义上讲,闭包特性 指的是函数可以保存并访问其词法作用域的这一种特性/能力,或者叫函数可以记住并获取其函数定义时上下文。用到闭包 指的是依然存在/拥有对那个函数保存的词法作用域的引用。
-
函数拥有这个特性与将此特性应用出来是两回事。当函数执行完毕,一般期望此函数的作用域A消失且 作用域上定义的变量 都得到内存回收♻️,特性的应用就是仍有存在对这个函数作用域A的变量引用,A仍在使用。
-
通常人们讲的’这是一个闭包、这称为闭包、闭包、这构成闭包’指的是闭包特性使用,即 存在对保存的那个词法作用域的引用/访问。
// first 应用词法作用域链的例子
function foo() {
var a = 'foo'
function bar () {
console.info(a)
}
bar()
}
foo()
// first- 应用词法作用域链的另外的例子
function _foo () {
var a = '_foo'
function bar (b) {
console.info(b)
}
bar(a)
}
_foo()
// second 应用词法作用域的例子
function fee(a) {
function bar () {
console.info(a)
}
bar()
}
fee('fee')
// second- 应用词法作用域另外的例子
function _fee(a) {
function bar(b) {
console.info(b)
}
bar(a)
}
_fee('_fee')
// third 闭包的例子
function fff(a) {
return function bar () {
console.info(a)
}
}
fff('fff')()
// third- 另外的闭包的例子
function _fff() {
const a = '_fff'
return function bar () {
console.info(a)
}
}
_fff()()
// third- 糟糕的错误例子
// function _fff(a) {
// (function(b) {
// return function bar() {
// console.info(b)
// }
// })(a)
// }
// _fff('_fff')()
// forth
function fgg() {
let a = 'fgg'
function bar (b) {
a += b
console.info(a)
}
return {
concat: function () {
bar('_concat')
},
splice: function () {
bar('_splice')
}
}
}
fgg().concat()
fgg().splice()
const $fgg = fgg()
$fgg.concat()
$fgg.splice()