Js中闭包的概念、原理、作用及应用菜鸟教程_闭包小白基础

一、闭包概念闭包:有权访问另一个函数作用域中的变量的函数,一般情况就是在一个函数中包含另一个函数。从官方定义我们知道闭包是一个函数,只不过这个函数有[超能力],可以访问到另一个函数的作用域。为什么说这个叫做[超能力]呢?因为我们知道函数作用域是独立的、封闭的,外部的执行环境是访问不了的,但是闭包具有这个能力和权限。那闭包是怎样的一个表现形式呢?第一,闭包是一

Js中闭包的概念、原理、作用及应用菜鸟教程

一、闭包概念
闭包:有权访问另一个函数作用域中的变量的函数,一般情况就是在一个函数中包含另一个函数。
从官方定义我们知道闭包是一个函数,只不过这个函数有[超能力],可以访问到另一个函数的作用域。
为什么说这个叫做[超能力]呢?
因为我们知道函数作用域是独立的、封闭的,外部的执行环境是访问不了的,但是闭包具有这个能力和权限。
那闭包是怎样的一个表现形式呢?
第一,闭包是一个函数,而且存在于另一个函数当中
第二,闭包可以访问到父级函数的变量,且该变量不会销毁

Js中闭包的概念、原理、作用及应用菜鸟教程_闭包小白基础

function person(){
    var name = '有鱼';
    function cat(){
        console.log(name);
    }
    return cat;
}
var per = person();// per的值就是return后的结果,即cat函数
per();// 有鱼 per()就相当于cat()
per();// 有鱼 同上,而且变量name没有销毁,一直存在内存中,供函数cat调用
per();// 有鱼

二、闭包原理
闭包的实现原理,其实是利用了作用域链的特性,我们都知道作用域链就是在当前执行环境下访问某个变量时,如果不存在就一直向外层寻找,最终寻找到最外层也就是全局作用域,这样就形成了一个链条。
例如:

var age = 18;
function cat(){
    age++;
    console.log(age);// cat函数内输出age,该作用域没有,则向外层寻找,结果找到了,输出[19];
}
cat();//19

看到这里,大家都会说这不就是最简单的函数和变量形式吗?闭包在哪里?别急,我们接着往下看:
如果我们再次调用时,结果会一直增加,也就变量age的值一直递增。

cat();//20
cat();//21
cat();//22

如果程序还有其他函数,也需要用到age的值,则会受到影响,而且全局变量还容易被人修改,比较不安全,这就是全局变量容易污染的原因,所以我们必须解决变量污染问题,那就是把变量封装到函数内,让它成为局部变量。

function person(){
    var age = 18;
    function cat(){
        age++;
        console.log(age);
    }
    return cat;
}
person();// 19
person();// 19

这里又出现问题了,每次调用函数person,进入该作用域,变量age就会重新赋值为18,所以cat的值一直是19;所以需要做一下调整:

var per = person();//per相当于函数cat
per();// 19 即cat() 这样每次调用不在经过age的初始值,这样就可以一直增加了
per();// 20
per();// 21

而且变量age在函数内部,不易修改和外泄,相对来说比较安全。

Js中闭包的概念、原理、作用及应用菜鸟教程_闭包小白基础

三、闭包作用
作用1:隐藏变量,避免全局污染
作用2:可以读取函数内部的变量
同时闭包使用不当,优点就变成了缺点:
缺点1:导致变量不会被垃圾回收机制回收,造成内存消耗
缺点2:不恰当的使用闭包可能会造成内存泄漏的问题
这里简单说一下,为什么使用闭包时变量不会被垃圾回收机制收销毁呢,这里需要了解一下JS垃圾回收机制;
JS规定在一个函数作用域内,程序执行完以后变量就会被销毁,这样可节省内存;使用闭包时,按照作用域链的特点,闭包(函数)外面的变量不会被销毁,因为函数会一直被调用,所以一直存在,如果闭包使用过多会造成内存销毁。

四、闭包应用
需求:实现变量a 自增
1、通过全局变量,可以实现,但会污染其他程序

var a = 10;
function Add(){
    a++;
    console.log(a);
}
Add();
Add();
Add();

 2、定义一个局部变量,不污染全局,但是实现不了递增

var a = 10;
function Add2(){
    var a = 10;
    a++;
    console.log(a);
}
Add2();
Add2();
Add2();
console.log(a);

3、通过闭包,可以是函数内部局部变量递增,不会影响全部变量,完美!!

var a  = 10;
function Add3(){
    var a = 10;
    return function(){
        a++;
        return a;
    };
};
var cc =  Add3();
console.log(cc());
console.log(cc());
console.log(cc());
console.log(a);

 

海计划公众号
(0)
上一篇 2020/03/20 07:33
下一篇 2020/03/20 07:32

您可能感兴趣的内容

  • Bootstrap-waterfall使用帮助一款基于Bootstrap仿Pinterest网站的网格瀑布流插件

    Bootstrap-waterfall基础入门 官方网址:https://mystist.github.io/bootstrap-waterfall/ GitHub:https:/…

    2020/03/05
  • js检测页面上一个元素是否已经滚动到了屏幕的可视区域内基础知识_js知识基础教程

    应用场景:只要页面加载了,其中在页面中出现的li就向控制台输出第几个发送请求;在本次加载的页面中,再将滚动条滚回前边的li,不再向控制台输出东西,也就是说已经显示过的li,不再向控制台输出东西。

    • 0001
    • 0002
    • 0003
    • 0004</li
    2020/04/05
  • javascript初学者可以看什么书?小白教程_书籍指南攻略

    在javascript的入门阶段,通过书籍来学习对于新手来说才是最好的手段。书籍的学习固然比较枯燥,但是也是最权威,最系统化的,对于新手来说能够快速的完成基础知识的奠基,而对于之后进一步的提升也是大有裨益。下面就为各位javascript初学者推荐几本不容错过的javascript书籍。1、《javascript面向对象编程指南》,风格轻松易懂,比较适合初学

    2020/03/20
  • DefinePlugin插件用法理解入门百科_插件使用帮助

    一、官方定义:DefinePluginDefinePlugin 允许创建一个在编译时可以配置的全局常量。这可能会对开发模式和生产模式的构建允许不同的行为非常有用。如果在开发构建中,而不在发布构建中执行日志记录,则可以使用全局常量来决定是否记录日志。这就是 DefinePlugin 的用处,设置它,就可以忘记开发环境和生产环境构建的规则。new webpack

    2020/03/23
  • 面试中突然遇到答不上的问题怎么办?小白攻略_面试指南教程

    前言今天给大家讲讲面试过程当中最长遇到的窘境,也是最能体现一个候选人临场应变能力的地方,那就是当我们在面试的过程当中,遇到的问题回答不上来的时候,该怎么办。误区在开始讲解之前,先纠正一个误区,那就是对于一场面试而言,最后的结果好坏并不完全取决于面试当中的问题是否都回答了上来。能不能录取和是否回答出所有问题并没有直接的联系。换句话说,我自己经历过的,无论是面试

    2020/03/23
  • JS 自执行函数小白指南_函数小白教程

    由于自己js基础知识薄弱,很多js的知识还没有掌握,所以接下来会经常写一些关于js基础知识的博客,也算给自己提个醒吧。js自执行函数,听到这个名字,首先会联想到函数。接下来,我来定义一个函数:function aaa(a,b){return sum = a + b
    }定义了一个名为aaa的函数,在里面可以计算两个数的和。如果想执行它,就必须得调用它,并且还得

    2020/03/29
  • Class 的私有属性与私有方法零基础入门_Class基础知识教程

    proposal-class-fields与proposal-private-methods定义了 Class 的私有属性以及私有方法,这 2 个提案已经处于 Stage 3,这就意味着它们已经基本确定下来了,等待被加入到新的 ECMAScript 版本中。事实上,最新的 Chrome 已经支持了 Class 私有属性。那么,对于 Class 的私有属性与私

    2020/03/30
  • 纯 JS 设置文本框的默认提示菜鸟教程网_input小白教程

    HTML5 中有个新特性叫 placeholder,一般用它来描述输入字段的预期值,适用于 text、search、password 等类型的 input 以及 textarea。示例如下:
    <input type="search" placeholder="请输入查询关键

    2020/03/26
  • 是不是人人都可以做程序员?入门教程_程序员使用帮助

    最近刚忙完一个项目,在做项目总结的时候,有一个强烈的感觉,同样都是带出两年的徒弟,在项目实际开展过程中展示的成果结果差别都有几倍的关系了。大家都是在一个起跑线上为啥差异这么大?是不是什么人都能做程序员?一系列的疑问在脑中呈现,这么多疑问归结起来:什么样的人适合做程序员?善于思考发现总结问题,并且积极的进补的人。程序员是一个对细节把控相当严苛的职业,无数的细节

    2020/04/03
  • 面试时如何优雅地自我介绍?菜鸟指南_面试小白知识

    1.题记有读者提问:如何在面试当中做一个最好的自我介绍?结合了一下自己面试以及面试别人(模拟面试)的一些经验,简单总结了几点,供大家参考。2.为什么要自我介绍在面试官要求自我介绍后,有些同学会觉得信息都在简历上,于是就 简单粗暴 地说:“面试官好,我叫阿客,我的信心简历上都有,我就 不赘述 了…了…了…”。咳咳,面试的时候就这么狂,你是要上天啊.

    2020/03/24
  • 关于鼠标移动太快导致moseleave事件不触发的问题零基础入门_事件基础知识教程

    描述:我做的是一个table的编辑功能,当移入某行的时候展示编辑状态,在移出某行的时候显示的是原始状态,此时遇到一种情况,就是当mousenter事件触发之后,由于鼠标移动得太快,同一个tr上绑定的mouseleave事件压根儿就没有执行。如果此时想要在mouseenter中做节流,那么这么多的tr,该怎么样区分呢?我这里采用的方式是,在mouseenter

    2020/03/31
  • 云路课堂入门指南专业的职业技能学习平台,免费课程很多

    云路课堂小白攻略 官方网址:http://www.yun.lu/student/homepage 简介描述:专业的职业技能学习平台,免费课程很多

    2020/03/06
  • JavaScript 的代理对象小白基础_对象菜鸟指南

    JavaScript 支持 setters 和 getters 已经很长时间了。他们用带有 set 和 get 关键字的简单语法来拦截对象的属性访问和值的修改操作。const obj = {propValue: 1,get prop() {console.log(“Retrieving property prop”);return this.propValu

    2020/03/22
  • Logaster菜鸟知识_在线免费创建简单logo及名片设计

    Logaster菜鸟知识 官方网址:https://www.logaster.cn/ 简介描述:在线免费创建简单logo及名片设计 Logaster 是一个专业的在线LOGO图标制…

    2020/03/10
  • php底层原理之垃圾回收机制小白帮助_内存基础知识教程

    php垃圾回收机制,对于PHPer来说是一个不陌生但是又不是很熟悉的内容。那么php是怎么实现对不需要的内存进行回收的呢?php变量的内部存储结构首先还是需要了解下基础知识,便于垃圾回收原理内容的理解。大家都知道php是由C编写而成的,所以php变量的内部存储结构也会和C语言相关,即zval的结构体:struct _zval_struct {union {l

    2020/03/31
  • 程序员面试必备的5个问题入门教程_面试小白知识

    年年有面试,岁岁有面试.如果说工作内容占据了职业生涯的90%,那么面试就占据了10%.面试决定了我们是否可以进入某个公司,是否可以谈判一个较高的薪水,是否可以胜任某些重要的职位.千万不要以为技术水平决定了你的工资和等级,如果不能有一个好的面试过程,那么之后的试用期和正式期除了任务的数量和困难程度可能指数级增加以外,其他的并不会改变.就算短时间做出超越几倍的努

    2020/03/24