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垃圾回收机制( 从这个角度也能了解把函数赋值给全局变量全局变量依赖内函数,那么内函数里面的变量就不能被清除【阮一峰的理解】 )

  • 相关阅读:
    HTML DOM 12 表格排序
    HTML DOM 10 常用场景
    HTML DOM 10 插入节点
    HTML DOM 09 替换节点
    HTML DOM 08 删除节点
    HTML DOM 07 创建节点
    022 注释
    024 数字类型
    005 基于面向对象设计一个简单的游戏
    021 花式赋值
  • 原文地址:https://www.cnblogs.com/wchjdnh/p/10800246.html
Copyright © 2011-2022 走看看