1. 闭包的定义
闭包的产生条件
当一个嵌套的内部函数引用了的嵌套的外部函数的变量时,就产生了闭包
function fn1(){
var a = 2
var b = 'abc'
function fn2() {//定义时就会产生
console.log(a)
}
}
fn1()
此时fn2内部产生了闭包,但只包含a
闭包的定义
(可以使用chrome调试查看)
浅:闭包是嵌套的内部函数
深:包含被引用变量(函数)的对象
两个点:嵌套 and 引用
2.闭包的作用和生命周期
2.1 将函数作为另一个函数的返回值
function fn1() {
var a = 2//此时闭包产生,因为函数提升
function fn2() {
a++
console.log(a);
}
return fn2
}
var f = fn1()
f()
f()
f = null //闭包死亡(包含闭包的函数对象成为垃圾对象)
只产生了一个闭包,所以a的值累加
这就显示出了闭包的两个作用:
1. 使用函数内部的变量a在函数执行完后,仍然存活在内存中(延长了局部变量的生命周期)
2. 让函数外部可以操作函数内部的数据
请编写一个方法getprim() ,依次输出质数,不能使用全局变量,函数本身不接受任何参数
const isprim = (num) => {
for(let i = 1 ; i<=num ;i++){
if(num%i == 0 && i!==1 && i!==num) return false
}
return true
}
function getprim(){
let i = 2
const prim = () =>{
while(!isprim(i))i++
console.log(i++);
}
return prim
}
let getp = getprim()
getp()
getp()
定义prim时,闭包形成,gep每次调用都在同一个闭包中操作。
2.2 将函数作为实参传递给另一个函数调用
function showDelay(msg,time) {
setTimeout(() => {
alert(msg)
}, time);
}
showDelay('mt',2000)
2.3闭包的生命周期
闭包产生于:内部嵌套函数定义执行完
闭包死亡于:嵌套的内部函数成为垃圾对象
3.闭包的缺点
- 函数执行完后,函数内的局部变量没有释放,占用内存时间会变长
- 容易造成内存泄漏(占用的内存不被释放)
4.内存溢出与内存泄漏
溢出:内存溢出是一种程序运行出现的错误,当程序运行需要的内存超过了剩余的内存时,就抛出内存溢出的错误
泄露:占用的内存没有及时释放,泄漏多了就会内存溢出
导致内存泄漏的情况:1.意外的全局变量 -》 用var、let、const声明变量
2.setinterval -》用clearInterval
3.闭包 -》 f = null
5.综合面试题
function fun(n,o) {
console.log(o);
return {
fun:function(m){
return fun(m,n)
}
}
}
var a = fun(0); a.fun(1);a.fun(2);a.fun(3) //u 0 0 0
var b = fun(0).fun(1).fun(2).fun(3)// u 0 1 2
var c = fun(0).fun(1); c.fun(2);c.fun(3)//u 0 1 1
关键在于有没有产生新的闭包