简易版“闭包”,一看就能学会

抽象沙漏
• 阅读 1221

一、为什么会产生闭包?

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

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

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

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

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 组成了一个闭包

四、闭包的缺点是什么?

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

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

五、使用闭包的注意点

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

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

点赞
收藏
评论区
推荐文章
Dax Dax
4年前
JS核心原理理解闭包
前置概念在正式看闭包之前,我们先来学习一下前置知识,那就是JS中的作用域,我们知道,在ES5之中,作用域分为两种:全局作用域和函数作用域,随着ES6的到来,新增了块级作用域,想更好的理解闭包,那么搞清楚作用域是首要条件全局作用域我们知道,对于变量而言,我们一般会分成两类:全局变量和局部变量,一般定义在最外围环境的为全局变量,定义在函数当中的为局部变量,在we
Karen110 Karen110
3年前
一篇文章带你了解JavaScript作用域
在JavaScript中,对象和函数也是变量。在JavaScript中,作用域是你可以访问的变量、对象和函数的集合。JavaScript有函数作用域:这个作用域在函数内变化。一、本地JavaScript变量一个变量声明在JavaScript函数内部,成为函数的局部变量。局部变量有局部作用域:它们只能在函数中访问。JS://codeherecann
Jacquelyn38 Jacquelyn38
4年前
你不可不知的JS面试题(第三期)
1、什么是闭包?如图所示,闭包就是一个定义在函数内部的函数,其作用是将函数内部和函数外部连接起来。大家知道,作用域的问题,就是在函数内部定义的变量称为局部变量,外部取不到值。下面我们通过代码来更加详细地看一下:function A()       let x  1;       return function B()           c
菜园前端 菜园前端
2年前
一篇文章教会你什么是闭包
原文链接:什么是闭包?闭包的概念并不复杂,但是它的定义比较绕(就像平时经常用到它,却又说不出来是什么)。可以在一个作用域中调用函数的内部函数并访问到该函数中的作用域的成员,这就是闭包。给一个建议,网上闭包的概念可以搜出来一大堆,但是你真的了解它吗?你有去调
菜园前端 菜园前端
2年前
为你解惑JS作用域和作用域链知识
原文链接:变量作用域一个变量的作用域(scope)是程序源代码中定义这个变量的区域。全局变量拥有全局作用域,在JavaScript代码中的任何地方都是可以访问的。然而在函数内声明的变量只能在函数体内访问,它们是局部变量,作用域是局部性的。函数参数也是局部变
Bill78 Bill78
4年前
Python 中的闭包
闭包定义:如果在一个内部函数里,对在外部作用于(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包Python中的闭包原文出处:田小计划(http://www.cnblogs.com/wilber2013/p/4658894.html)闭包(closure)是函数式编程的重要的语法结构
Jacquelyn38 Jacquelyn38
4年前
你所知道的JS变量作用域
变量的作用域,指的是变量在脚本代码中的可读、可写的有效范围,也就是脚本代码中可以使用这个变量的区域。在ES6之前,变量的作用域主要分为全局作用域、局部作用域(也称函数作用域)两种;在ES6及其之后,变量的作用域主要分为全局作用域、局部作用域、块级作用域这3种。相应作用域变量分别称为全局变量、局部变量、块级变量。全局变量声明在所有函数之外;局部变量是在函数体内
Wesley13 Wesley13
3年前
JS 闭包(内存溢出与内存泄漏)(垃圾回收机制)
1.有关闭包定义闭包是指有权访问另一个函数作用域中变量的函数,创建闭包的最常见的方式就是在一个函数内创建另一个函数,通过另一个函数访问这个函数的局部变量闭包的特性:函数内再嵌套函数内部函数可以引用外层的参数和变量参数和变量不会被垃圾回收机制回收
Stella981 Stella981
3年前
JS的数组,string类的定义及基本方法
函数:函数在调用的时候,会形成一个私有作用域,内部的变量不会被外面访问,这种保护机制叫闭包。这就意味着函数调用完毕,这个函数形成的栈内存会被销毁。functionfn(){vara12;a;console.log(a)}fn()13fn()13fn()13但有时候我们不希
Stella981 Stella981
3年前
JavaScript函数——闭包
闭包概念只有函数内部的子函数才能读取局部变量,所以闭包可以理解成“定义在一个函数内部的函数“。在本质上,闭包是将函数内部和函数外部连接起来的桥梁例子functionouter(){varlocalVal30;returnlocalVal;}
小万哥 小万哥
1年前
Python 作用域:局部作用域、全局作用域和使用 global 关键字
变量只在创建它的区域内可用。这被称为作用域。局部作用域在函数内部创建的变量属于该函数的局部作用域,并且只能在该函数内部使用。示例:在函数内部创建的变量在该函数内部可用:pythondefmyfunc():x300print(x)myfunc()函数内部的函
抽象沙漏
抽象沙漏
Lv1
天长地久有时尽,此恨绵绵无绝期。
文章
4
粉丝
0
获赞
0