设为首页 加入收藏

TOP

作用域和闭包的通俗理解(二)
2018-03-18 16:21:17 】 浏览:511
Tags:作用 包的 通俗 理解
le.log(a)
        console.log(d)
      }
      fn2()
    }
    fn1()


闭包就是能够读取其他函数内部数据(变量/函数)的函数。


只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成"定义在一个函数内部的函数"。


上面这两句话,是阮一峰的文章里的,你不一定能理解,来看下面的讲解和举例。


当一个嵌套的内部(子)函数引用了嵌套的外部(父)函数的变量或函数时, 就产生了闭包。


注意: 闭包存在于嵌套的内部函数中。


来看看条件2:


    functionfn1() {
        functionfn2() {


        }


        return fn2;
    }


    fn1();


上面的代码不会产生闭包,因为内部函数fn2并没有引用外部函数fn1的变量。


PS:还有一个条件是外部函数被调用,内部函数被声明。比如:


    functionfn1() {
        var a = 2
        var b = 'abc'


        functionfn2() { //fn2内部函数被提前声明,就会产生闭包(不用调用内部函数)
            console.log(a)
        }


    }


    fn1();


    functionfn3() {
        var a = 3
        var fun4 = function () {  //fun4采用的是“函数表达式”创建的函数,此时内部函数的声明并没有提前
            console.log(a)
        }
    }


    fn3();


    functionfn1() {
      var a = 2


      functionfn2() {
        a++
        console.log(a)
      }
      return fn2
    }


    var f = fn1();  //执行外部函数fn1,返回的是内部函数fn2
    f() // 3      //执行fn2
    f() // 4      //再次执行fn2


当f()第二次执行的时候,a加1了,也就说明了:闭包里的数据没有消失,而是保存在了内存中。如果没有闭包,代码执行完倒数第三行后,变量a就消失了。


上面的代码中,虽然调用了内部函数两次,但是,闭包对象只创建了一个。


也就是说,要看闭包对象创建了一个,就看:外部函数执行了几次(与内部函数执行几次无关)。


    functionshowDelay(msg, time) {
      setTimeout(function() {  //这个function是闭包,因为是嵌套的子函数,而且引用了外部函数的变量msg
        alert(msg)
      }, time)
    }
    showDelay('atguigu', 2000)


上面的代码中,闭包是里面的funciton,因为它是嵌套的子函数,而且引用了外部函数的变量msg。


我们让然拿这段代码来分析:


    functionfn1() {
      var a = 2


      functionfn2() {
        a++
        console.log(a)
      }
      return fn2
    }


    var f = fn1();  //执行外部函数fn1,返回的是内部函数fn2
    f() // 3      //执行fn2
    f() // 4      //再次执行fn2


作用1分析


上方代码中,外部函数fn1执行完毕后,变量a并没有立即消失,而是保存在内存当中。


作用2分析:


函数fn1中的变量a,是在fn1这个函数作用域内,因此外部无法访问。但是通过闭包,外部就可以操作到变量a。


达到的效果是:外界看不到变量a,但可以操作a


比如上面达到的效果是:我看不到变量a,但是每次执行函数后,让a加1。当然,如果我真想看到a,我可以在fn2中将a返回即可。


回答几个问题:


答案:一般是不存在, 存在于闭中的变量才可能存在。


闭包能够一直存在的根本原因是f,因为f接收了fn1(),这个是闭包,闭包里有a。注意,此时,fn2并不存在了,但是里面的对象(即闭包)依然存在,因为用f接收了。


不能,但我们可以通过闭包让外部操作它。


(1)myModule.js:(定义一个模块,向外暴露多个函数,供外界调用)


functionmyModule() {
    //私有数据
    var msg = 'Smyhvae Haha'


    //操作私有数据的函数
    functiondoSomething() {
        console.log('doSomething() ' + msg.toUpperCase()); //字符串大写
    }


    functiondoOtherthing() {
        console.log('doOtherthing() ' + msg.toLowerCase()) //字符串小写
    }


    //通过【对象字面量】的形式进行包裹,向外暴露多个函数
    return {
        doSomething1: doSomething,
      &

首页 上一页 1 2 3 4 下一页 尾页 2/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Android基础知识:Activity中获取.. 下一篇Kotlin/Native应用程序开发指南

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目