闭包
闭包是一个函数的高级应用
条件
当出现了一个不销毁的函数执行空间
在 A 函数内部 直接或者间接 返回一个函数 B
被返回的 B 函数使用着 A 函数内部的数据
我们把 b 叫做 a 的闭包函数
function a() {
var num = 100
function b() {
console.log( num )
}
return b
}
var res = a()
闭包的特点:
闭包的每个优点都伴随了一个缺点 (这个缺点是致命的)
- 延长了变量的声明周期 一个不会销毁的函数执行空间
- 可以在函数外部访问函数内部的数据 一个不会销毁的函数执行空间
- 变量私有化(只要是函数就有这个特点) 在函数外部不能访问函数内部的变量 如果想访问的话就要出现闭包
闭包的致命缺点:
- 因为内存空间是固定的
- 每一个闭包会占用一段时间内存空间
- 当闭包过多的时候,内存空间就会占用越来越多
- 当闭包过多的时候会导致 内存溢出(也就是内存泄漏)
function a() {
var num = 100
var num2 = 200
return function b() {
console.log(num)
}
}
var res = a()
// console.log(num) // => 报错 num is not defiend
res() // => 100
res = null
直接返回一个函数
function a() {
var num = 100
return function b() {
return num
}
}
// 我的 res 接受的就是函数 a 返回的那个 函数 b
var res = a()
// 当我的 res 执行的时候就能得到函数 a 内部的 num 变量
var n = res()
console.log(n)
function fn(i) {
return function (n) {
console.log(n + (--i))
}
}
var f = fn(2)
f(3) // 4
// fn(4) 用返回值再次调用
fn(4)(5) // 8
// var a = fn(4)
// a(5)
fn(6)(7) // 12
// var b = fn(6)
// b(7)
f(8) // 8
var n = 1
var obj = {
n: 2,
fn: (function () {
this.n += 2
n *= 3
return function(){
this.n *= 2
n += 1
console.log(n)
}
})(n)
}
// 全局变量 fn 和 obj.fn 操作一个函数地址
// 都是那个自执行函数的返回值函数
var fn = obj.fn
// 调用方式 全局调用
// this => window
fn() // 19
// 调用方式 对象调用
// this => obj
obj.fn() // 20
console.log(n, obj.n) // 20, 4