Day.26 「闭包要谨慎使用!」 —— JavaScript 闭包(Closure)

「闭包要谨慎使用!」 —— JavaScript 闭包(Closure)

我们前面已经认识了函式作用域,也了解了回调函式,但有时候会产生意想不到的事情,造成内存问题,其中一个是闭包

认识闭包

闭包是如何产生的?

闭包通常出现在巢状函式中,是内部函式使用了外部函式变数时,产生闭包

闭包是什麽?

首先我们用简单的范例

function fn() {
  var a = 1;
  function plus1() {
    a++
    console.log(a);
  }
  return plus1;
}

var f = fn();
f();

我们透过 Google Chrome 的开发人员工具查看执行过程

Google Chrome 的开发人员工具

可以看到在执行到第 8 行的时候,产生了闭包,也就是红框处!

由此可见~闭包是在我们内部函式使用到了外部函式的变数时产生出来。
你可能想说第 9 行函式还没执行呀!?
那是因为,函式的提升,所以导致执行到函式变数的时候就产生闭包。
而这时有被内部函式使用的变数,就会存在闭包之中!

常见的闭包

内部函式 为 外部函式 的返回值

就是我们上面的范例

function fn() {
  var a = 1;
  function plus1() {
    a++
    console.log(a);
  }
  return plus1;
}

var f = fn();

f();  // 2
f();  // 3

你会发现!函式内的变数 a 还存在可以累加并没有消失,而这个值就存在 f 函式的闭包中!

回调函式

没错!回调函式也会产生闭包~如下面范例

function consoleDelay (msg, time) {
  setTimeout( function() {
    console.log(msg)
  }, time)
}

consoleDelay("我也是闭包", 2000);

一样有形成闭包的条件!内部函式引用了外部函式的变数!

我也是闭包

闭包的作用

  1. 一般函式执行完毕後,就会从内存释放,而闭包则是把函式内的变数,继续保留在内存中(延长了局部变数的生命周期)。

  2. 一般函式内的变数无法从外部操作,但闭包可以间接操控函式内部的变数值。

闭包的优点与缺点

闭包的优点同时也是缺点

  • 函式执行完後,函式内的局部变数不会释放,如果这个局部变数还会使用,那就是优点,如果不会使用了,那就变成缺点,因为占用内存的时间会变长。

    function fn() {
      var arr = new Array(10000);
      function arrLength() {
        console.log( "内存有 " + arr.length + " 长度的阵列" );
      }
      return arrLength;
    }
    
    var f = fn();
    f();  // 内存有 10000 长度的阵列
    
  • 容易造成内存溢出泄漏

    • 内存溢出比较简单理解,就是内存不够跑程序而报错
      内存溢出
    • 内存泄漏平常还可以正常执行,但每天泄漏一点,会把内存空间压缩,更容易导致内存溢出,常见的内存泄漏
      • 意外使用了全局变数(宣告习惯很重要),如:函式内忘记使用宣告,直接使用变数
      • 没有及时清理的计时器回调函式
      • 闭包

如何解决

  • 尽量避免滥用闭包

  • 及时释放

    f = null;  // 让内部函式变成「垃圾物件」,浏览器会自动清除
    

总结

我们已经逐步学习 JavaScript 的核心精随了!也是面试很长考的观念~


<<:  图的储存结构 - 相邻串列 - DAY 21

>>:  Day 23 云上大数据分析

Day 1 Introduction

前情提要 我是 siriuskoan,在这三十天内会把一些关於 flask 的知识写成文章,以供自己...

虹语岚访仲夏夜-7(专业的小四篇)

如果,我留下足迹,却无人发现, 算不算可惜。 如果,我遇见了我的足迹, 却浑然不知, 何以证明,是...

Day19 Redis架构实战-持久化AOF

Redis持久化 Redis持久化模式->AOF AOF (Append Only File)...

你想成为的是?

早起运动Day11 - 来自周遭的祝福​ ​ 「你知道吗?当时最让我触动的地方,是你接受了我的情绪。...

【Day 05】C 的资料型态(上)

今天一开始,我们先来讲讲基本的常识~~ 甚麽是位元、位元组? 位元(bit)可以保有两种资料(0 和...