【JavaScript闭包】初识JavaScript闭包问题

JavaScript闭包问题的理解

今天早上打开B站看见一道关于JavaScript闭包的题,看了看,发现自己不太理解闭包,所以就查阅资料和思考来理解一下闭包~(最后会加上那个题的!)
     关于对JavaScript闭包问题的理解
一、变量作用域
  理解闭包之前,一定要理解变量作用域,JavaScript 变量可以是局部变量或全局变量。
  • 全局变量
  • 局部变量
  1. 全局变量

函数可以访问由函数内部定义的变量

var a = 4;
function myFunction() {
    return a * a;
}
  1. 局部变量

函数可以访问函数外部定义的变量

function myFunction() {
    var a = 4;
    return a * a;
}
二、那么什么是闭包呢

闭包是指有权访问另一个函数作用域中的变量的函数。也就是说,闭包可以让你从内部函数访问外部函数作用域

为什么要闭包?
优点

  1. 闭包使外部得以访问函数内部的变量。
  2. 避免全局变量的使用,防止全局变量污染(匿名函数)。
  3. 让某些关键变量得以常驻内存,免于被回收销毁(闭包函数)内部函数保留了对外部函数的活动便利的引用,所以变量不会被释放。一些不经常变动计算起来又比较复杂的值保存起来,节省每次的访问时间。
  4. 封装私有变量,我们可以把函数当做一个范围,函数内部的变量就是私有变量,在外部无法访问,但是我们可以通过闭包的特点来访问私有变量。

缺点

  • 会造成内存泄漏:有一块内存空间被长期占用,而不被释放

  • 导致变量不会被垃圾回收机制回收,造成内存消耗

闭包是一种保护私有变量的机制,在函数执行时形成私有的作用域,保护里面的私有变量不受外界干扰。直观的说就是形成一个不销毁的栈环境

三、那么如何从外部读取全局变量呢
正常情况下,外部是没有办法访问局部变量的,但是我们有时候需要得到函数内部的局部变量,那么此时我们该如何做?

方法:我们可以在函数的内部,再定义一个函数

function foo() {
    var a = 123

    function bar() {
        console.log(a);
    }
    bar()
}

foo(); // 123

  • bar在foo内部, 此时foo内部的所有的局部变量对bar都是可见的
  • 但是bar内部的局部变量却是对foo不可见
  • 其实这是JavaScript特有的‘链式作用域’结构,(它是就近原则,子对象会一级一级的向上寻找所有父对象的变量),因此,父对象的所有变量,对子对象都是可见的,反之则不成立

从上面的那个例子我们可以看出,bar可以获取foo中的局部变量,那么我们可以思考,要是把bar作为返回值,我们是不是可以在foo外部读取它的局部变量呢

下面这个例子:

function foo() {
    var a = 123

    function bar() {
        console.log(a);
    }
    return bar;
}

var p = foo();
p(); //123

  • 从上面我们可以得出,函数内返回函数是可以获取它的上一级函数的局部变量,这就是闭包问题。
四、闭包的注意事项
  • 通常,函数的作用域及其所有变量都会在函数执行结束后被销毁。
  • 但是,在创建了一个闭包以后,这个函数的作用域就会一直保存到闭包不存在为止,因为闭包就是一个函数引用另外一个函数的变量,因为变量被引用着所以不会被回收。这是优点也是缺点,不必要的闭包只会徒增内存消耗,
  • 所以我们在使用的时候需要注意这方面。可以通过设置null手动释放对闭包的引用。

在B站上看到的那个闭包题

//以下的代码执行后,console输出的答案是?
      function fun() {
        var i = 0;
        return function () {
          console.log(i++);
        };
      }
      var f1 = fun();
      var f2 = fun();
      f1();
      f1();
      f2();

所以答案是什么呢?

0
1
0

其实很简单嘿嘿

f1 f2 产生闭包,各自保存一份变量i,每调用一次函数,输出i的值,然后执行i++。注意:输出时i的值为还没加1,输出后i的值才加1。 i++ 与 ++i 的区别

关于闭包其实还会涉及很多东西,鉴于我现在知识体系较薄,后续遇到问题,会继续研究哒~

加油啦

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

东非不开森

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值