JavaScript闭包基础指南

闭包是函数创建时范围内所有变量的集合。要使用闭包,请在另一个称为嵌套函数的函数内创建一个函数。内部函数将有权访问外部函数范围中的变量(Closure有助于访问外部函数范围),即使在返回外部函数之后也是如此。每次创建函数时都会创建闭包。

在继续了解闭包之前,让我们首先了解一下JavaScript作用域链。

通常,范围有两种:

  • 全局作用域

  • 局部作用域

在ES5版本中,函数内部的变量在外部不可见。但是,块内部的变量(条件如if或while)在外部也可见。

由此,ES5具有功能范围。没有块作用域。

根据ES5,使用函数是在代码中声明块作用域的唯一方法。

但是,在ES6中,通过提供块范围的let和const关键字可以缓解这种情况。

无论如何,最好了解JavaScript是如何逐步发展的。

让我们在ES5版本中继续:

var a = 10;
function app(){
   var b = 2;
   console.log(a); // 10
   console.log(b); // 2
}
console.log(b); //   ReferenceError: b is not defined
app();

我们已经知道,a是全局变量,b是特定于app函数的局部变量。

我们无法从局部范围中获取局部变量的值。

使用嵌套函数-函数内的函数

var a = 10;
function app(){
     var b = 2;
     var d = 3;
  function add(){
     var c = a + b;
   }
 return add;
}
var x = app();
console.dir(x);

在这里,app是父函数,add是子函数。

使用console.dir而不是使用console.log来控制指定JavaScript对象的所有属性,帮助开发人员获取该对象的属性

变量x被分配给app函数,而app函数返回add函数。 因此,我们可以看到add函数的所有对象属性。

如果在浏览器中看到控制台,则可以在Scopes数组中看到Closure对象。

1.jpg

由于内部函数添加访问外部函数变量b和d,所以这两个变量将被添加到闭包对象中以供引用。

让我们来看下一个闭包的例子:

var a = 10;
var startFunc;
function app(){
      var b = 2;
   function add(){
      var c = a + b;
      console.log(c);
   }
   startFunc = add();
}
app(); // Invoke the app function
startFunc; 
// as the app function invoked above will assign the add function to startFunc & console the value of c
  • 一个名为startFunc的全局函数被分配给add函数,add函数是父app函数的子函数。

  • 这只有在调用app函数之后才可能实现,否则startFunc将作为一个全局变量,没有任何赋值

闭包在JavaScript中的应用

我们大多数人在编码时使用闭包,但我们不知道为什么要使用闭包。JavaScript不像其他面向对象的编程语言那样具有私有公共受保护等访问修饰符。因此,我们必须使用函数来保护名称空间不受ES5中外部代码的使用。

特别是在函数中,立即调用的函数表达式(IIFE)是在声明之后立即执行的表达式。不需要在函数声明之后调用该函数。

IIFE允许用JavaScript编写模块模式(设计模式之一)。

IIFE的语法定义为:

(function(){
             //variables & scope that inside the function 
})();

让我们举个例子:

var studnetEnrollment = (function () {
    //private variables which no one can change
    //except the function declared below.
     var count = 0;
     var prefix = "S";
    // returning a named function expression
     function innerFunc() {
         count = count + 1;
         return prefix + count;
     };
 return innerFunc;
})();
var x = studnetEnrollment(); // S1
console.log(x);
var y = studnetEnrollment(); // S2 
console.log(y);

count和prefix是两个私有变量,不能被任何人改变,只能被内部函数访问(这里是它的innerFunc)。这种访问只能通过称为闭包(Closure)的特性实现。

  • 在第一次调用studentEnrollment函数时,函数中的count变量被innerFunc函数递增1。

  • 在第二次时,计数将递增计数的前一个值,即1到2

  • 这些都可以通过闭包特性实现。

结论

闭包是外部函数中的变量集合,它允许访问内部函数作用域来保护全局命名空间。

闭包使开发人员能够编写干净的代码,就像OOP语言一样,不会混淆ES5版本中的全局变量名和局部变量名。

快乐编码……! ! ! ! !

英文地址原文:https://www.freecodecamp.org/news/a-basic-guide-to-closures-in-javascript-9fc8b7e3463e/

Image placeholder
前端答疑
未设置
  81人点赞

没有讨论,发表一下自己的看法吧

推荐文章
可视化的JavaScript:JavaScript引擎运行原理

JavaScript很酷,但是JavaScript引擎是如何才能理解我们编写的代码呢?作为JavaScript开发人员,我们通常不需要自己处理编译器。然而,了解JavaScript引擎的基础知识并了解

JavaScript基础之 DOM简介

JavascriptDOM(文档对象模型)是一个允许开发人员操纵页面内容、结构和风格的接口。在本文中,我们将理解什么是DOM以及如何用Javascript去操作它。本文还可以作为基本DOM操作的参考。

喊话 JavaScript 开发者:玩 DOM 也要专业范儿

别再害怕DOM了,让我们充分挖掘DOM的潜力,你会真的爱上它。 2008年,当我刚成为一名专业Web开发人员参加工作时,我了解一些HTML、CSS和PHP的知识。那时我也在学习JavaScript

JavaScript 的数据结构和算法

现在有个还不是好的项目,未来会成为好的项目的项目想介绍给大家。传送门https://github.com/MasterShu/JavaScript-Da...这个是本人在维护的一个项目。主要是使用Ja

JavaScript 安全知识: CORS 简明教程

概述浏览器会强制同源策略以禁止不同源的网站获得响应; 『同源策略』不会阻止对其他来源的请求,但是会禁用JavaScript对响应内容的读取。 -CORS标头允许访问跨域响应。 -CORS与凭证一起需要

一起来学 TypeScript

鉴于JavaScript社区正式更名为F2E前端,我就大胆的把我另外一个项目也放上来。😄这个项目是关于TypeScript,是个人记录TypeScript的学习历程以及各个常用库的TypeScript

5种用于前端开发的JavaScript替代方案

JavaScript虽然是很受欢迎的语言,但是并不适合所有人,那么有哪些替代方案呢?本文将分析5种JavaScript替代方案。1995年,Netscape(网景通信公司)聘请BrendanEich为

javascript如何判断是不是整数?

方式一、使用取余运算符判断任何整数都会被1整除,即余数是0。利用这个规则来判断是否是整数。functionisInteger(obj){ returnobj%1===0 } isInteger(3);

9 个顶级的JavaScript图表库

数据可视化技术在过去十年中一直在不断改进,现在许多高级图表库可供消费者使用。在2000年代初期,图表生成主要由服务器端图像位图构成。诸如Flash和Silverlight之类的插件提供了更具交互性的图

先学php还是javascript?

javascript是前台的东西,PHP是后台的东西,两者先学谁都是一样的。两者之间没有啥实质性的必然联系。Javascript就是浏览器执行的脚本语言,控制页面内容。php就是服务器端执行的语言,读

深入了解JavaScript async/await !

Asyncfunctions让我们以async这个关键字开始。它可以被放置在任何函数前面,像下面这样:asyncfunctionf(){ return1; }在函数前面的「async」这个单词表达了一

JavaScript中对“this”的简单理解

1.this的奥秘很多时候,JS中的this对于咱们的初学者很容易产生困惑不解。this的功能很强大,但需要一定付出才能慢慢理解它。对Java、PHP或其他标准语言来看,this表示类方法中当前对象的

JavaScript中的强制类型转换

JavaScriptprimitives(原语)JavaScript建立在一系列基本单元之上。你应该对其中的一些已经很熟悉了,比如字符串和数字:vargreet="Hello";varyear=89;

如何使你的JavaScript代码简单易读

解决同一问题的方法有很多,但有些解决方法很复杂,甚至有些是荒谬的。在这篇文章中,我想谈谈解决同样问题的好方法和坏方法。让我们先从怎样删除数组中的重复项这个简单问题开始。复杂-使用forEach删除重复

JavaScript中的Infinity(无穷)

Infinity(无穷)在JS中是一个特殊的数字,它的特性是:它比任何有限的数字都大,如果不知道Infinity,我们在一些运算操作遇到时,就会觉得很有意思。现在我们来看看JS中的Infinity属性

浏览器中的JavaScript:什么是文档对象模型?什么是DOM操作?

JavaScript并没有那么糟糕。作为运行在浏览器中的脚本语言,它对于网页操作非常有用。在本文中,我们将看到可以用哪些手段来修改HTML文档和交互。什么是文档对象模型?文档对象模型是在浏览器中一切的

JavaScript 变量提升(Hoisting)

'提升'是每个JS开发人员都听说过的一个术语,如果你刚接触JS,可能会遇到一些“怪异”的行为,其中某些变量是随机undefined,会抛出ReferenceErrors异常等等。Hoisting通常被

不使用JavaScript创建常见UI元素功能

我们已经习惯于用JavaScript编写常见的UI元素功能(如手风琴、工具提示、文本截断等),但是随着HTML和CSS有了新的功能以及旧版浏览器不再受支持,我们越来越少使用JavaScript来创建U

javascript怎么清除CSS样式?

javascript怎么清除CSS样式?一、使用setAttribute方法清除样式dom结构helloworldjavascriptp.setAttribute('style','');二、使用re

一些JavaScript 类(class)中需要了解的知识

JavaScript使用原型继承:每个对象都从原型对象继承属性和方法。在Java或Swift等语言中使用的传统类作为创建对象的蓝图,在JavaScript中不存在,原型继承仅处理对象。原型继承可以模拟

14个你可能不知道的JavaScript调试技巧

以更快的速度和更高的效率来调试JavaScript熟悉工具可以让工具在工作中发挥出更大的作用。尽管江湖传言JavaScript很难调试,但如果你掌握了几个技巧,就能用很少的时间来解决错误和bug.文中

如何通过 Tampermonkey 快速查找 JavaScript 加密入口

在很多情况下,我们可能想要在网页中自动执行某些代码,帮助我们完成一些操作。如自动抢票、自动刷单、自动爬虫等等,这些操作绝大部分都是借助JavaScript来实现的。那么问题来了?在浏览器里面怎样才能方

jquery和javascript有关系吗?

jquery和javascript有关系吗?有关系,具体的关系是:jquery是基于JavaScript编写的,jquery全部都是JavaScript代码组成。jquery和javascript的关

可视化的JavaScript:作用域(链)

首先,来看看下面的代码:constname="Lydia" constage=21 constcity="SanFrancisco" functiongetPersonInfo(){ constn

可视化的JavaScript:事件循环

首先,事件循环是什么,为什么要理解它?JavaScript是单线程的:一次只能运行一个任务。通常这没什么大不了的,但现在想象一下我们正在运行一个需要30秒的任务。在这个任务中,我们要等待30秒,然后才