zoukankan      html  css  js  c++  java
  • js闭包

    在写这篇博客之前,其实我对闭包的理解停留在两个函数嵌套内函数可以访问外函数,会产生内存泄露这两个点上,确实也就这两个点,但是如果有人问你使用场景呢?为什么要用内函数去获取外函数的局部变量?有可能你会说返回给全局啊,这样全局可以用了,是的,但是,如果使这种需求,我直接把局部变量return 出去不就行啦,何必要再声明一个函数呢?

    有人又会说内存泄露,你又猜对了,但是真的有人问你为什么会造成内存泄露,能举一个简单例子吗?你能写出来吗?能的话说明你不仅懂了闭包,其实你也已经懂了js回收机制。直到我看了阮一峰老师的文章确实简单易懂,在此谢谢并友情链接:http://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures.html

    容我像一个初学者一样慢慢道来:

    // 最简单的闭包
        function outer() {
            var a = 1;
            function inner() {
                console.log(a)
            }
    // return a }

    这是一个闭包,但这不足以造成内存泄露,如果想要返回局部变量a的值,直接在outer里 return a,所以说这么普通的闭包真的是又麻烦又没有任何效果

    // 返回一个函数
        function outer() {
            var a = 1;
          return function inner() {
                console.log(a)
            }
        }

    这回高级一点了,返回了一个函数,那么返回一个函数难道就为了让外界获取局部a的值吗?显然有些花里胡哨,还是直接return a不好吗?花里胡哨复杂的代码,别人几行就能搞定,你说哪个牛?而用简单的方法就能实现的更牛。所以函数作为返回值绝不是仅仅用来让外界获取a的值的,而是外界更贪心,还想改变a的值。怎么做呢?请看:

    function outer() {
            var a = 1;
          return function inner() {
                a = a + 1;
                console.log(a)
            }
        }
        
        // 调用返回的函数,闭包会导致每次调用都初始化,得出来的结果都一样,我们需要的是初始化步骤一次就够剩下的只交给inner()
        outer()();  // 2
        outer()();  // 2

    这不是闹着玩吗?outer()就是inner函数,outer()()就是inner() 再来几个outer()()都是2,这是因为每次执行outer()都会把a重新赋值为1,我就要每次调用inner()就要把a自增

    // 闭包式调用 --- 这是我自己添加的名词,不是官方的,这其实就是摆脱了每次调用inner还要执行一次outer
        var fn = outer();
        fn() // 2
        fn() // 3

    其实就是把返回的函数赋给了一个全局变量,简简单单的赋值,这就厉害了,如果用fn去掉用,就不会走var a = 1这条语句,也就是说不会在outer内重新赋值,而a不会走正常局部变量的该走的道路(局部变量执行就回收)。这就体现了第二个特点:局部变量难以回收。(造成内存泄漏) 这功能倒是适应以下情况:想让一个局部变量在原先处理的基础上操作,但是又需要初始化(这很重要),不想每次执行都把局部变量初始化了。有人一看:这简单,直接在全局里面写不就行了(码农);全局里面全局污染怎么办(相当于钱的余额能给别人查看和修改吗)程序员), 防止全局污染使用函数,而在函数内要满足上述要求使用闭包,所以闭包也能防止变量污染。

    斐波那契递归实现(闭包缓存版):

    // 使用闭包缓存会减少很多的重复操作
        function fbnq(n){
            var cache = []
           return function handle() {
                var res;
                if(n == 1 || n == 2){
                    return 1;
                }
                if (cache[n] == res){
                    return cache[n]
                }else{
                    res = fbnq(n-1) - fbnq(n-2)
                    cache[n] = res;
                    return res;
                }
            }
            return handle
        }


    闭包讲完了,下面有兴趣的大佬们可以看看相关博客(其实是想听听大佬们的指点): js垃圾回收机制( 从这个角度也能了解把函数赋值给全局变量全局变量依赖内函数,那么内函数里面的变量就不能被清除【阮一峰的理解】 )

  • 相关阅读:
    解决Tomcat请求中文乱码的问题
    Bootstrap 兼容 IE
    Spring+MyBatis多数据源配置实现
    年度总结与计划
    AJAX 提交表单以及文件上传
    移动端Web开发调试工具:Chrome DevTools
    SpringMVC 之 @ResponseBody 和 @RequestBody
    goland快键键防忘
    MySQL日志文件影响数据库的各种类型活动
    何为云计算
  • 原文地址:https://www.cnblogs.com/wchjdnh/p/10800246.html
Copyright © 2011-2022 走看看