eclipse关闭代码说明_请说明关闭!

eclipse关闭代码说明

(本文是来自旧金山的软件工程师Nathan Thomas正在进行的有关软技能和技术向导的系列文章的一部分。单击 此处 ,以获得系列文章中的上一篇文章“ Building Your First GraphQL Server”。单击 此处 以获取下一篇文章系列文章中的一篇文章,名为“构建您的第一个GraphQL服务器”。)

从外而内

解释闭包是一个经常使用JavaScript访谈问题,但是许多工程师仍然不完全了解它们的工作方式。 周围弥漫着雾气,就像假期中吃得太多时的感觉。 🥧

当我刚开始学习关闭方法时,我的第一要冲动就是关闭笔记本电脑的屏幕,然后呆呆地盯着当地的池塘。 但是不用担心; 闭包吸引了很多人,但是到本文结尾,您将了解它们的工作原理和背后的概念。

我将向您介绍一个非常酷(更重要的是, 简单 )的示例。 您将很快获得它。

拿起您喜欢的咖啡,苹果酒,热巧克力或冬季饮料,让我们开始吧。 ☕️

“我会以任何借口购买新的背包。” -迈克尔·波茨

拿起你的背包

封闭是一个有趣的概念。 它们在您的代码中是真正不可见的,但它们是非常真实的。 如果您编写了任何JavaScript,几乎可以肯定地使用了它们,甚至没有意识到。

如果没有别的,那应该给你安慰; 如果您已经意外地成功使用了它们,那么成功的一半将是学习它们背后的想法,以填补它们工作方式的空白。

从根本上讲,闭包是变量的无形分隔,可在各个级别(例如,全局范围,局部函数范围等)访问您的代码。

每次编写函数时,都会为其可用的作用域创建一个闭包。 JavaScript会自动执行此操作,因此我们需要做的就是了解它。

例如,假设我们有以下代码:

const globalVariable = 1 ;

function createClosure ()  {
  const localVariable = 2 ;
  return function ()  {
    return globalVariable + localVariable;
  }
}

const closure = createClosure();

console .log(closure()); // returns 3

此代码会将数字3到控制台。 JavaScript为幕后代码创建了多个作用域; 有一个与全局范围globalVariable中,并与当地的范围localVariable globalVariable在他们访问。

这是包含注释的相同代码,以指示哪些部分是全局范围和局部范围:

// global scope with globalVariable available
const globalVariable = 1 ;

function createClosure ()  {
  // local scope with localVariable and globalVariable available
  const localVariable = 2 ;
  return function ()  {
    // local scope with localVariable and globalVariable available
    return globalVariable + localVariable;
  }
}

const closure = createClosure();

console .log(closure()); // returns 3

停下来想一想这里发生了什么。 createClosure函数可以访问两个变量。

如果我告诉过您,当函数在其他地方(甚至是另一个文件)使用时,可以在函数创建时使用闭包访问作用域中所有变量的功能该怎么办?

我知道。 科学走得太远了吗?

让我们找出答案。 🧪

一个好的旅行者没有固定的计划,也不打算到达。”-老子

闭包计数

这是本文其余部分将要处理的代码。 继续阅读。 👍

如果您还不了解它与闭包之间的关系,请不要担心。 只需了解一下代码实际上在做什么:

function createCountingClosure ( startingNum )  {
  if ( typeof startingNum !== "number" ) return null ;
  let num = startingNum;
  function increment ()  {
    num++;
    return num;
  }
  function decrement ()  {
    num--;
    return num;
  }
  function getNum ()  {
    return num;
  }
  return [increment, decrement, getNum];
}

当我们调用该函数时,会得到以下结果:

const [increment, decrement, getNum] = createCountingClosure( 0 );

此外,我们可以调用这些incrementdecrement ,并getNum功能得到如下:

increment();// 1
increment(); // 2
increment(); // 3
decrement(); // 2
increment(); // 3
getNum(); // 3

不用担心 我们将详细研究这段代码,以弄清楚到底发生了什么。

(旁注-我们正在这里进行一些重组。如果您不知道什么是重组,请不用担心。请在此处查看MDN的精彩文章。)

让我们再次看一下createCountingClosure函数并分解每个部分:

function createCountingClosure ( startingNum )  {
  if ( typeof startingNum !== "number" ) return null ;
  let num = startingNum;
  function increment ()  {
    num++;
    return num;
  }
  function decrement ()  {
    num--;
    return num;
  }
  function getNum ()  {
    return num;
  }
  return [increment, decrement, getNum];
}

首先,我们接受一个名为startingNum的参数。 我们显然希望它是一个数字(因为下一行是if语句,如果不是,则返回null )。

接下来,我们将startingNum的值分配给num变量。 这为我们的计数器功能提供了一个开始使用的值,以后可以更改。

然后,我们继续声明三个函数:

  1. increment ,增加num的值并返回其值
  2. decrement ,它减小num的值并返回其值
  3. getNum ,它返回num的当前值

最后,我们将这三个函数返回到数组中。 由于函数是JavaScript中的“一等公民”,因此我们可以像这样传递函数,以从函数中返回并在其他地方使用。

这就是为什么我们以后可以调用createCountingClosure并对这三个函数进行解构的原因:

const [increment, decrement, getNum] = createCountingClosure( 0 );

如您所见,我们还将0传递给函数。 还记得我们如何设置它以接受startingNum参数吗? 在此示例中,该值将为0

综上所述,我们现在讨论createCountingClosure函数,在这里我们可以讨论闭包的工作方式。

坚持住你的屁股。

包里面有什么?

让我们再次看一下createCountingClosure函数:

function createCountingClosure ( startingNum )  {
  if ( typeof startingNum !== "number" ) return null ;
  let num = startingNum;
  function increment ()  {
    num++;
    return num;
  }
  function decrement ()  {
    num--;
    return num;
  }
  function getNum ()  {
    return num;
  }
  return [increment, decrement, getNum];
}

当我们宣布incrementdecrementgetNum ,我们在不知不觉中创造了他们每个人的那家商店访问可用的所有变量在其范围时,创建这些功能关闭小“背包”。

还记得本文开始时我们是如何进行全球范围和本地范围的吗? 还记得我们创建的函数如何在本地范围内保留对全局范围内的globalVariable访问吗?

好吧,同样的事情在这里发生。 对于实例, increment功能保留对num变量的访问。 实际上,所有这些函数以后仍然可以在我们可能使用它们的任何位置访问该变量(即使它在另一个文件中)。

例如,还记得我们调用createCountingClosure时如何对所有这些函数进行结构createCountingClosure

const [increment, decrement, getNum] = createCountingClosure( 0 );

这是如上所述的increment函数在被解构时可以访问(在代码中)的内容:

let num = startingNum;
function increment ()  {
  num++;
  return num;
}

即使我们仅对incrementincrement ,它仍然可以访问num变量。 它位于功能的关闭背包中,就像很小的尤达一样。

这意味着即使我们没有直接在函数内部包含它,也可以访问和修改 num变量。

那不疯狂吗? 🦁

decrementgetNum也是如此。 从创建时开始,它们都可以以相同的方式访问num

让我们继续使用我们的代码,看看它是如何工作的。

“如果我能看到这个世界,我会很高兴地背着背包生活。” -未知

更新背包

我们将使用我们的代码并逐步完成它,以观察它的作用。 在开始之前,请先整理一下整个过程:

function createCountingClosure ( startingNum )  {
  if ( typeof startingNum !== "number" ) return null ;
  let num = startingNum;
  function increment ()  {
    num++;
    return num;
  }
  function decrement ()  {
    num--;
    return num;
  }
  function getNum ()  {
    return num;
  }
  return [increment, decrement, getNum];
}

另外,我们将像以前一样调用createCountingClosures函数并解构数组中返回的函数:

const [increment, decrement, getNum] = createCountingClosure( 0 );

通过此设置,我们现在可以开始使用了。 如果您想在我们浏览本文其余部分的同时进行操作,这里有一个Codepen链接 ,可让您与代码进行交互。

首先,我们将调用增量函数:

increment();// should return 1

如前所述, increment函数保留对num变量的访问。 当我们调用increment ,该函数将在后台增加num的值。

由于我们最初在上方调用createCountingClosures时传入了0值,因此我们将该值增加到1

(如果您遵循我提供的CodePen,则会在控制台中看到该弹出窗口,因为我已将函数调用包装在console.log 。)

接下来,我们将再调用两次增量,如下所示:

increment();// should return 2
increment(); // should return 3

注意,每次返回的值都不是从1开始; 这是因为我们上面使用的相同变量num也被increment保留,并在每次调用时进行修改。 这是关闭的不可思议的力量!

接下来,我们将调用函数decrement来减小num的值:

decrement();// should return 2

请注意,该值再次不是从0开始。 函数decrementincrement都保留对同一num变量的访问,并且共享修改它的能力,即使该变量未包含在两个变量中。

最后,我们getNum调用一次increment并通过调用getNum函数(此函数仅返回num的当前整数值)来限制increment

increment();// should return 3
getNum(); // 3

所有这些函数调用都可以访问num变量,因为它们所有对它的引用都存储在它们的小范围“背包”中。

最终的getNum调用返回3,这是我们对其进行的所有更改中的num的值。 即使num并不直接包含在我们一直调用的任何函数中,我们还是通过闭包的功能对其进行了修改。

如果您仍然难以掌握封包的工作原理,以下是MPJ(在YouTube上运行Fun Fun Function频道)上的精彩短片,介绍了封包的工作原理:

结论

我希望这个关于闭包如何工作的简短介绍可以帮助您掌握它们。

通过将它们想象成函数在应用程序中移动时会磨损的小背包,您可以在心中建立一个框架,了解如何访问和操作闭包中包含的变量。

另外,既然我们已经逐步介绍了它们的工作原理,那么您可以对自己的结业知识充满信心,并粉碎下一次面试的机会。

谢谢阅读。 🔥

内森

Twitter的 LinkedIn GitHub Portfolio网站

翻译自: https://hackernoon.com/please-explain-closures-g73q3w1h

eclipse关闭代码说明

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值