likes
comments
collection
share

被众多程序员誉为js难度第一的闭包

作者站长头像
站长
· 阅读数 29

码文不易,请未来的大厂程序员们动动发财的小手点点赞

前言

在程序员们聊到js时,应该都会被闭包的概念所吸引,因为闭包被誉为js最难理解的知识。 既然如此,我们就去攻克它

闭包是什么

  • 根据js词法作用域的规则,内部函数总是能访问外部函数中的变量,当通过调用一个外部函数返回的一个内部函数后,即使外部函数执行已经结束了,但是内部函数引用了外部函数中的变量也依旧需要被保存在内存中,我们把这些变量的集合叫做闭包 我们看个例子
function bar(){
    console.log(a);
}
function foo(){
    var a =100
    bar()
}
var a = 200
foo()
我们在上面已经学习过了作用域
就一步步分解上面的代码
从全局开始,变量a=undefined,foo()=function foo(){},
进入foo()函数a=100,bar()=function bar(){}
进入bar(),变量里没有元素,
开始运行,a=200,foo(),a=100,bar(),console.log(a)
此时应该输出100
让我们看看答案

被众多程序员誉为js难度第一的闭包

问题就是在于,bar()的outer指向的是全局,bar()函数并没有在foo函数体里 当改成这样


function foo(){
    function bar(){
    console.log(a);
}
    var a =100
    bar()
}
var a = 200
foo()

输出就为100 被众多程序员誉为js难度第一的闭包

开始进阶

function add(){
    var count = 0;
    function foo(){
        count++;
        return count;
    }
    return foo;
}

var bar = add()

console.log(bar())
console.log(bar())
console.log(bar())
一步步解析
全局上下文 bar=undefiner,
进入add(),count = undefined,foo()
开始运行:
调用add()函数,运行function foo(),count++,count=1,返回count,foo函数结束,把1赋值给foo返回给add(),bar = add(),console.log(bar()),输出1
连续执行三次,是不是每次都从count=0开始,最后输出1,1,1
我们来看结果

返回的值是1,2,3

被众多程序员誉为js难度第一的闭包 在我们的惯用思维下,就应该是1,1,1,但结果是1,2,3, 这就是js中特殊的闭包

被众多程序员誉为js难度第一的闭包 在每次console.log(bar())时,都会调用一次add(),在闭包里的count会每次都++

闭包概念

无论何时声明新函数并将其赋值给变量,都要存储函数定义和闭包。闭包包含在函数创建时作用域中的所有变量,它类似于背包。函数定义附带一个小背包,它的包中存储了函数定义创建时作用域中的所有变量。

简化来说,只要一个函数没有被调用,而是用return来返回其函数体中变量的值时,就会产生闭包

其实,用window来将变量放入全局,也是同理。

闭包的作用

  • 作用
    • 实现公有变量(企业的模块开发)
    • 做缓存
    • 封装模块,防止全局变量污染

在大型程序的开发中,闭包往往起到非常重要的作用,因为每个人负责一部分功能,难免在设置变量时,变量名会重合,用闭包封装,就会避免被全局变量污染

闭包的缺陷

闭包有个巨大的缺陷,就是会占用栈的内存,如果一个程序使用了大量的闭包方法,就会挤压栈的空间,导致内存泄漏

结语

对闭包概念的理解,是每个程序员都难以逃脱的宿命,希望这篇文章可以给你启发。

转载自:https://juejin.cn/post/7373645836871876618
评论
请登录