一、为什么会产生闭包?

在开始说闭包之前,我们要先理解一下变量的作用域,变量的作用域无非有两种:全局作用域和局部作用域。

出于种种原因,有时候我们需要得到函数内部的局部变量。

但是,在正常情况下这个是办不到的,只有通过变通的方法才能实现。

这个方法就是,在函数的内部再定义一个函数。

function f1() {  
    let a = 1  
  function f2() {  
        console.log(a);  
  }  
}

在上面的代码中,函数 f2 就被定义在了 函数 f1 中,这时 f1 内的所有局部变量对 f2 都是可见的。

但是反过来就不行,f2 内部的局部变量对 f1 就是不可见的。

那么既然 f2 可以读取 f1 中的变量,那么只要把 f2 作为返回值,我们不就可以在 f1 外部读取它内部的变量了吗!

function f1() {  
    let a = 1  
  function f2() {  
        console.log(a);  
  }  
    return f2;  
}  
  
var result = f1();  
  
result()

二、闭包是什么?

定义:如果一个函数用到了外部的变量,那么这个函数加这个变量,就叫做闭包。

比如,这里就是一个闭包:

function f1() {  
    let a = 1  
  function f2() {  
        console.log(a);  
  }  
}
// 函数 f2 可以访问外部的变量 a,那么函数 f2 和 外部的变量 a 就构成了闭包

三、闭包的作用是什么

闭包常常用来间接访问一个变量,换句话说,就是隐藏一个变量。

假如我们在开发一个商城项目,里面有产品数量的代码。如果不使用闭包,那么你可以直接使用一个全局变量:

window.number = 200

这样子写存在一个问题,万一不小心把这个值改成了 0 该怎么办,所以我们不能让人直接访问这个变量。

使用局部变量?使用局部变量别人又无法进行访问。

可以暴露一个访问器(函数),让别人可以“间接访问“。

代码可以这样子写:

!function () {  
    var number = 200  
  window.addGoods = function () {  
        number += 1  
  }  
    window.deleteGoods = function () {  
        number -= 1  
  }  
}()  
  
window.addGoods()

这个时候,你就可以调用 window.addGoods 来添加商品,调用 deleteGoods 来下架商品。

这其中一共有两个闭包:

  • number 和 addGoods 组成了一个闭包
  • number 和 deleteGoods 组成了一个闭包

四、闭包的缺点是什么?

由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页性能问题。

解决方法是,在退出函数之前,将不适用的局部变量全部删除。

五、使用闭包的注意点

闭包会在父函数外部改变父函数内部的值。

所以,如果你把父函数当做对象使用,把闭包当做他的公用方法,把内部变量当做它的私有属性,这时一定要小心,不要随便改变父函数内部变量的值。


前端_杭州求职中
21 声望3 粉丝

引用和评论

0 条评论