什么是闭包
闭包就是能够读取其他函数内部变量的函数
形成闭包的条件
- 嵌套函数
- 嵌套函数内部引用了外函数的私有变量
- 嵌套函数被外部变量引用
闭包的特点
- 利用闭包可访问函数内部的私有变量
- 若存在引用,则闭包及内部私有变量不会被垃圾回收且长驻内存
- 嵌套函数有独有的arguments,无法直接访问外函数的arguments
- 嵌套函数的this指向直接调用对象
但是如果这个函数定义了嵌套的函数,并将它作为返回值返回或者存储在某处的属性里,这时就会有一个外部引用指向这个嵌套的函数。它就不会被当做垃圾回收,并且它所指向的变量绑定对象也不会被当做垃圾回收 --- JavaScript权威指南
1. 关联作用域
let name = '张三', age = 20
function userInfo() {
let name = '李四'
return function () {
console.log(name,age)
}
}
userInfo()() // 李四, 20
函数的执行依赖于变量作用域,这个作用域是在函数定义时决定的,而不是函数调用时决定的。--- JavaScript权威指南
2. 变量常驻内存
function addCount () {
let count = 0
return function () {
return ++count
}
}
let count = addCount() // 调用addCount,返回待执行的嵌套函数
count() // 1
count() // 2
嵌套函数被返回,且被外部变量引用,嵌套函数内部也引用了外函数的私有变量。因而导致私有变量未被垃圾回收,函数也不会被销毁
3. 作为暴露私有变量的特权方法
function Fun() {
let name = '张三'
this.getName = function() {
return name
}
}
let f = new Fun()
f.getName() // 张三
无法通过实例化访问构造函数的私有变量,因为可在构造函数中定义特权方法暴露私有变量