专业编程基础技术教程

网站首页 > 基础教程 正文

前端面试必问之JavaScript中的闭包,超详解

ccvgpt 2024-10-12 14:20:27 基础教程 11 ℃

点关注,不迷路,每天大量前端资料更新

闭包

function fn1(){
 var a = 2
 function fn2(){
 conso1e.log(a) //fn2引用了fn1函数中的变量a,产生了闭包
 }
}
fn1()

如何产生闭包

当一个嵌套的内部(子)函数引用了嵌套的外部(父)函数的变量(函数)就产生了闭包(满足了这个条件就是闭包),如上例子

前端面试必问之JavaScript中的闭包,超详解

闭包到底是什么

通过Chrome中的调试工具查看

理解一:闭包是嵌套的内部函数(绝大部分人)认为上例子中的fn2

理解二:包含在被引用变量(函数)的对象(极少数人)认为上例子的变量a

注意:闭包产生在嵌套的内部函数中

产生闭包的条件

1.函数嵌套

2.内部函数引用了外部函数的数据(变量或函数)

3.外部函数被执行(不用调用内部函数)

常见的闭包

1.将一个函数作为另一个函数的返回值

2.将函数作为实参传递给另一个函数调用

1.将一个函数作为另一个函数的返回值

function fn1(){
 var a = 2
 function fn2(){
 a++
 conso1e.log(a) 
 }
 return fn2
}
 var f = fn1()
 f() //3
 f() //4
 f = null //在嵌套的内部函数成为垃圾对象,就是闭包死亡

2.将函数作为实参传递给另一个函数调用

function showDelay(msg,time){
 setTimeout(function(){
 alert(msg)
 },time)
}
showDelay('alibaba',2000)

闭包的作用

使用函数内部的变量在函数执行后,仍然存活在内存中(延长了局部变量的生命周期)

让函数外部可以操作读写到函数内部的数据

函数执行完后,函数内部声明的局部变量是否还存在?

一般不存在,在有闭包的情况下,存在,仅仅闭包中的变量在闭包中,在函数执行完后存在,别的在函数执行完后都会释放

在函数外部能直接访问函数内部的局部变量吗?

不能,但是闭包的技术可以

闭包的产生,在嵌套的内部函数定义执行完就产生了(不是在执行时)

死亡:在嵌套的内部函数成为垃圾对象,就是死亡

闭包的应用

1.定义js模块:具有特定功能的js文件,将所有的数据和功能都封装在一个函数内部中

只向外暴露一个包含n个方法的对象或者函数,模块的使用者,只需要通过模块暴露的对象调用方法

来实现对应的功能

myModule.js如下

function myModule(){
 var msg = 'alibaba'
 function doSomething(){
 conso1e.log('doSomething()'+msg.toUpperCase())
 }
 function doOtherthing(){
 conso1e.log('doOtherthing()'+msg.toLowerCase())
 }
 //向外暴露一个包含n个方法的对象或者函数
 return{
 doSomething:doSomething
 doOtherthing:doOtherthing
 }
}

然后引入

<script src = 'myModule.js'></script>
<script>
 var moulder = myModule
 moulder.doSomething()
 moulder.doOtherthing()
</script>

闭包的缺点与解决方法

函数执行完后,函数内的局部变量没有释放,占用内存时间会变长

容易造成内存泄漏

function fn1(){
 var arr = new Array[1000000]
 function fn2(){
 conso1e.log(arr.length) 
 }
 return fn2
}
 var f = fn1()
 f = null //解决方法

解决

能不用闭包就不用,及时释放

内存泄露与内存溢出

内存溢出

一种程序运行出现的错误

当程序运行需要的内存超过剩余的内存时,就抛出了内存溢出的错误

内存溢出

var obj = {}
for (var i = 0;i<10000;i++){
 obj[i] = new Array(1000000000)
}

内存泄露

占用的内存没有及时释放

内存泄露积累多了就容易导致内存溢出

常见的内存泄露:

1.意外的全局变量

2.没有及时清理的计时器或回调函数

3.闭包

1.意外的全局变量

function fn(){
 a = new Array(1000000) //用var来申明才对
 conso1e.log(a)
}
fn() 在fn()执行后a并没有被释放

2.建立的定时器,必须清除

3.闭包

function fn1(){
 var arr = new Array[1000000]
 function fn2(){
 conso1e.log(arr.length) 
 }
 return fn2
}
 var f = fn1()
 //没有f = null

Tags:

最近发表
标签列表