媛技术贴

  • 首页
  • 微信小程序
  • 数据库
  • VueJs
  • 算法
  • 兼容性
  • 面试
  • React.js

闭包函数

发表于 2020-07-31 | 分类于 算法
贴上的标签: js 阅读时长 ≈ 7 分钟

普通函数内部可以直接读取全局变量。如:

 


local n = 1

function f1( ... )
    return n
end

print(f1())        --1


 

但普通函数内部却无法读取一个与自己不同作用域的局部变量。如:


function f1( ... )
    local n = 1
    return n
end

function f2( ... )
    print(n)
end

f2()        --nil


 

但是通过下列这种特殊的函数写法,就可以让一个函数读取一个与自己不同作用域的局部变量:


function f1( ... )
    local n = 1
    function f2( ... )
        n = n + 1
        return n
    end
    return f2
end

local result = f1()
print(result())        --2


 

在上面的代码中,函数f2就被包括在函数f1内部,这时f1内部的所有局部变量,对f2都是可见的。但是反过来就不行,f2内部的局部变量,对f1 就是不可见的。

既然f2可以读取f1中的局部变量,那么只要把f2作为返回值,我们就可以在f1外部读取它的内部变量!

 

这种函数叫称之为闭包函数。

所以,如果要用一句话说明白闭包函数,那就是:函数内在包含子函数,并最终return子函数。

而闭包函数的最大价值在于:我们可以在函数的外部(即子函数),直接读取该函数的局部变量。

再仔细研究,就会发现f1()函数就如同一个“类”,而其定义的局部变量就如同该“类”的全局变量;而子函数f2()函数,则如同这个“类”的方法,可以直接使用这个“类”的全局变量n。神奇吧?

 

现在总算明白什么是闭包函数了,虽然其实现很神奇,但闭包函数有什么用?

 

1、缓存:最显而易见的好处,就是可以实现数据缓存,我们可以把一个需要长期用到的变量设为闭包函数的局部变量,在子函数里面直接使用它。因此局部变量只定义初始化一次,但我们可以多次调用子函数并使用该变量。这比起我们在子函数中定义初始化变量,多次调用则多次初始化的做法,效率更高。闭包函数常见的一种用途就是,我们可以通过此实现计数功能。在闭包函数定义一个计数变量,而在子函数中对其进行++的操作。这样每次调用闭包函数,计数变量就会加1。


function f1( ... )
    local n = 0
    function f2( ... )
        n = n + 1
        return n
    end
    return f2
end

local count = f1()
print(count())        --1
print(count())        --2
print(count())        --3
print(count())        --4
print(count())        --5


 

2、实现封装:如同前面所说,闭包函数就如同一个“类”,只有在该闭包函数里的方法才可以使用其局部变量,闭包函数之外的方法是不能读取其局部变量的。这就实现了面向对象的封装性,更安全更可靠。

上一篇:匿名函数
下一篇:没有了
jing

Jing

座右铭:只有非常努力才会觉得毫不费力

92 总文章数
44 总标签
44 浏览人数
关于作者:前端代码搬运工
致力成为一个技术女肥宅
QQ:714195347
邮箱:714195347@qq.com
学前端找博主有海量资源等着你!!!
相关链接
  • Laravel China社区
  • GitHub
  • 橡皮擦擦
  • 资源作品集
  • 个人博客
© 2017 aicode.site by HUANGJING 阿里云计算有限公司
本站运行时长: 1948