美文网首页
043|JavaScript闭包

043|JavaScript闭包

作者: 中年小钢炮 | 来源:发表于2017-05-24 17:55 被阅读34次

    前面我们学习了函数,函数是一个包含可执行代码的对象。实际上,还有另一种包含可执行代码的对象,闭包。

    函数的嵌套定义

    一个函数的内部可以定义另一个函数,这叫做嵌套定义。嵌套定义的函数和普通函数没有什么区别。
    内部函数可以使用外部函数所能引用的变量,而外部函数无法引用内部函数的变量。
    我们通过一个例子来理解一下,如:

    function sayHi()
    {
        var name = "David";
        function getName()  // getName()是一个嵌套定义的函数
        {
            return name // 引用外部函数变量
        }
    
        console.log("Hello " +getName()) // 此处将会输出"Hello David"
    }
    
    sayHi()
    

    上述代码中定义了一个内部嵌套函数getName,getName引用了外部函数sayHi的变量。

    闭包

    上面代码中,内部的getName函数只在sayHi函数内部使用,所以getName是个普通函数。如果sayHi中将定义的getName函数返回到外部会怎么样?请看下面代码:

    function sayHi()
    {
        var name = "David";
        function getName()
        {
            return name
        }
    
        return getName //将getName函数返回到外部
    }
    
    var getName = sayHi() // 获取getName函数引用
    console.log(getName()) // 调用getName并输出结果
    

    上述代码将嵌套定义的getName函数返回到外部,并调用。我们来看一下运行结果:

    运行结果

    上述代码正常运行了getName函数。

    实际上,上述代码中的getName已经不再是个函数,而是一个闭包。

    闭包的英文是 Closure,它是JavaScript最重要的几个特性之一。闭包创建于当一个外部函数返回一个内部嵌套定义函数时。所以如果嵌套函数只在内部使用,而未通过retrun 语句抛出,则没能创建建闭包。

    闭包的本质

    为什么会有闭包呢?

    上一节我们学到,当一个函数执行完毕时,其内部变量将无法再被引用到,会被标致为垃圾然后被回收

    但在上述代码中,外部函数sayHi返回了一个内部函数getName,内部函数引用了外部函数的name变量,导致当sayHi结束运行时,name变量仍会被引用到

    为了保证name不会标记为垃圾,JavaScript对象创建一个闭包来引用name。对于上述程序,闭包本质就是一个下面这样的对象:

    closure = {
    name:name
    func:getName
    }
    

    本质上,一个闭包就是一个新建的对象,包含了内部函数执行时需要引用到的所有外部变量,以及内部函数本身。

    所以,一句话,闭包是为了嵌套函数能够在任何地方调用而创建的。

    好了,这一节就到这里。这一节内容较为抽象,希望你都掌握了。

    什么是索引容器?

    请继续关注我的课程,我将在后续课程中帮大家依次解答上述问题。

    想学计算机技术吗?需要1对1专业级导师指导吗?想要团队陪你一起进步吗?欢迎加我为好友!

    我的微信

    相关文章

      网友评论

          本文标题:043|JavaScript闭包

          本文链接:https://www.haomeiwen.com/subject/hnjoxxtx.html