何为闭包?
概念: 闭包就是指有权访问另一个函数中变量的函数.
创建闭包的常见方式,就是在一个函数内部创建另一个函数.
例子:
function create() {
let name = 'Conan'
return function() {
console.log(name)
}
}
在上面的例子中 内部函数 访问了 create 函数中的变量 name . 就算这个 内部函数 被返回了, 并且在其它地方进行调用了,但是它还能正常的范围 create 中的变量 name.
在函数被调用时, 会创建一个执行环境以及相应的作用域,然后使用arguments和其它命名参数的值进行初始化函数的活动对象. 每个执行环境中都有一个表示变量的对象 --- 变量对象. 全局的变量对象会一直存在, 但是像函数局部环境的变量对象,只有在函数执行时才存在.
那么为什么能访问呢? 答: 1.是因为内部函数的作用域中包含了,外部函数的作用域. 2.一般情况下当函数执行完后,局部活动对象就会被销毁,内存中只保留全局作用域(全局环境的变量对象),但是闭包就有所不同. 闭包的内部函数将会包含其外部函数的活动对象,将活动对象添加到自己的作用域中. 3.内部函数(匿名函数)被返回后,它的作用域被初始化并包含外部函数(create 函数)的活动对象和全局变量对象. 这样内部函数(匿名函数)就可以访问外部函数中的所有变量了. 4.更为重要的是 外部函数(create 函数)执行完毕后作用域会被销毁 但是其 活动对象 不会被销毁, 因为 内部函数 的作用域中还包含并引用了 外部函数(create 函数)的活动对象. 只有 内部函数(匿名函数) 被销毁后才会销毁 外部函数(create 函数) 的活动对象.
闭包和变量
概念: 闭包只能取得外部函数中任何变量的最后一个值.
例子:
function create() {
let res = []
for (var i = 0; i < 5; i++) {
res[i] = function() {
return i
}
}
return res
}
console.log(create()) // 结果: [4,4,4,4,4]
上面的例子中返回的结果差强人意吧, 从表面上看最终的结果应该是 [0,1,2,3,4]. 但是实际上结果却是 [4,4,4,4,4].
那么为什么会这样? 答: 因为每个函数的作用域中都保存着同一个 函数的活动对象(create 函数), 所以他们引用的都是同一个变量 i.
如何解决这个问题? 解: 我们可以使用匿名函数来创建一个闭包, 让闭包的行为来符合预期
```bash
function create() { let res = [] for (var i = 0; i < 5; i++) { res[i] = (function(num) { return function() { return num } })(i) } return res } console.log(create()) // 结果: [0,1,2,3,4]
上面将 create 函数进行了一个重写.
1.现在没有直接把闭包赋值给数组,而是再定义一个匿名函数, 将变量 i 当参数传进去由num来接收并立即执行.
2.在每次执行这个匿名函数时都会创建一个属于自己的 活动对象/作用域/变量对象.
3.然后再里面返回一个 只访问 num 的闭包函数, 这时取到的 num 都是独立的值
完结!!!!!!!!!!!!