闭包的示例_Javascript闭包的实际示例

闭包的示例

Most developers today, know about closures in Javascript. Don’t be sad if you don’t, it’s not something you generally use on your every-day work (well, you may, but it’s not so common).

今天中号 OST开发商,知道在Javascript关闭。 如果您不这样做,请不要感到难过,这不是您日常工作中通常使用的东西(虽然可以,但这并不常见)。

If you haven’t heard yet about closures, I recommend you to read this article: https://medium.com/javascript-scene/master-the-javascript-interview-what-is-a-closure-b2f0d2152b36

如果您尚未听说过闭包,建议您阅读这篇文章: https : //medium.com/javascript-scene/master-the-javascript-interview-what-is-a-closure-b2f0d2152b36

Closures are something that many companies would like you to know before working for them, therefore, chances are they’ll ask you something related with this topic, or even more, they could make you write a practical example of it.

闭包是许多公司在为他们工作之前希望了解的事情,因此,它们很可能会问您与该主题相关的问题,甚至更多,它们可能会让您写出一个实际的例子。

On this story, I’m gonna tell you about a small function I was asked to develop on an interview a while ago, that involved the use of closures for its solution.

关于这个故事,我要告诉您一个我在不久前的一次采访中被要求开发的小功能,其中涉及使用闭包作为其解决方案。

Let’s start with the premise:

让我们从前提开始:

Can you write a function that will solve the following test case?

您可以编写一个可以解决以下测试用例的函数吗?

let result = sum(1)(2)(3)();console.log(result === 6 ? 'SUCCESS' : 'ERROR');

The function we need to create will sum the values sent as a parameter and will accumulate them. Also, it will return another function for the next value to be passed on. If we don’t send any value to it, it will return the accumulated value.

我们需要创建的函数将对作为参数发送的值求和并进行累加。 同样,它将返回另一个函数以传递下一个值。 如果我们不向其发送任何值,它将返回累积的值。

It looks fairly simple at first, but let’s take a look into it:

首先,它看起来很简单,但让我们看一下:

const sum = (value) => {
let accum = 0; if (value) {
accum += value;
const innerSum = (value) => { /*TODO*/ };
} else {
return accum;
}
};console.log(sum());
0

That’s a good start. First, we create the function called sum that will take a value as a parameter. If that value exists, we will sum the value to the accum and return a function to keep adding values (TODO).

这是一个好的开始。 首先,我们创建一个名为sum的函数,它将一个value作为参数。 如果该值存在,我们将值和到accum和返回功能,以保持增加值(TODO)。

Let’s continue with the function:

让我们继续该功能:

const sum = (value) => {
let accum = 0; if (value) {
accum += value; const innerSum = (innerValue) => {
if (innerValue) {
accum += innerValue;
return innerSum;
} else {
return accum;
}
}; return innerSum;
} else {
return accum;
}
};console.log(sum(1)(2)(3)());
6

Cool, that works. Let’s recap: we called this new function innerSum, and, like the parent one, it receives a value and sums it. If what we sent to the function is a valid value, we will sum it to our accum and return the function itself, and if not, we will return the total value of the accumulator.

太好了,这可行。 让我们来回顾一下:我们将此新函数称为innerSum ,并且像父函数一样,它接收一个value并将其求和。 如果发送给该函数的是有效值,则将其求和到accum并返回该函数本身,否则,将返回累加器的总值。

As you can see, the closure was created inside the original sum function. The returned innerSum will maintain the lexical scope of the parent function, and therefore, it will keep the value of accum even after the initial function is not being used anymore.

如您所见,闭包是在原始 sum 函数 内部创建的 返回的 innerSum 将保持父函数的词法范围,因此, 即使不再使用初始函数 ,它也将保持 accum 的值

A closure is the combination of a function bundled together (enclosed) with references to its surrounding state (the lexical environment). In other words, a closure gives you access to an outer function’s scope from an inner function. In JavaScript, closures are created every time a function is created, at function creation time.https://medium.com/javascript-scene/master-the-javascript-interview-what-is-a-closure-b2f0d2152b36

闭包是捆绑在一起(封闭)的函数及其周围状态( 词汇环境 )的组合。 换句话说,闭包使您可以从内部函数访问外部函数的范围。 在JavaScript中,每次创建函数时都会在函数创建时创建闭包。 https://medium.com/javascript-scene/master-the-javascript-interview-what-is-a-closure-b2f0d2152b36

Great, it does what we want, but I think we can improve it more. Let’s refactor it a little bit:

很好,它可以实现我们想要的功能,但是我认为我们可以进一步改进它。 让我们重构一下:

const sum = (value) => {
let accum = 0;

const innerSum = (innerValue) => {
if (innerValue) {
accum += innerValue;
return innerSum;
} else {
return accum;
}
}; return innerSum;
};console.log(sum(1)(2)(3)());
5 // WRONG!

As you can see, we got rid of the initial check for the value, since we would always send at least 2 values (first one a number, last one undefined). But something’s not quite right, as you can see, the result is “5” instead of “6”. What happened here? At first sight, we can imagine that the first value was cut off somehow, but why?

如您所见,由于我们总是发送至少2个值(第一个为数字,最后一个为未定义),因此我们摆脱了对该值的初始检查。 但是有些不完全正确,如您所见,结果是“ 5”而不是“ 6”。 这里发生了什么? 乍一看,我们可以想象到第一个值以某种方式被切断了,但是为什么呢?

Well, what we are initially doing, is to create the acccum in 0 and then return the function, without adding the first number. An easy way to overcome this, is to initialise the accum with the first value we send. Also, we can add some validation to make sure a value is always sent as a first parameter:

好吧,我们最初要做的是在0中创建acccum ,然后返回该函数,而不添加第一个数字。 解决此问题的一种简单方法是使用我们发送的第一个值初始化accum 。 另外,我们可以添加一些验证以确保始终将值作为第一个参数发送:

const sum = (value) => {
let accum = value;

if (!value) {
return 0;
} const innerSum = (innerValue) => {
if (innerValue) {
accum += innerValue;
return innerSum;
} else {
return accum;
}
} return innerSum;
};console.log(sum());
0console.log(sum(1)(2)(3)());
6

Amazing! Now it looks much better. As you may be thinking, there’s still a lot of room for improvement, but we will leave it as it is and you can think by yourself on how we can refactor it or make it more efficient.

惊人! 现在看起来好多了。 正如您可能在想的那样,还有很多改进的余地,但是我们将保持现状,您可以自己考虑如何重构或提高效率。

下一步: (Next steps:)

  • Validate that the value sent is a number.

    验证发送的值是一个数字。
  • Allow the use of “0” as valid parameter.

    允许使用“ 0”作为有效参数。

结论 (Conclusion)

Closures are an easy way to achieve cool things like this one, but the most useful implementation, is to make global variables “private” using a similar method. This will let you avoid unwanted modifications to the variables inside of the scope you define, but you’ll need to provide a mechanism to modify those variables from the outside. Extra care needs to be taken when doing it though.

闭包是实现诸如此类的酷功能的一种简便方法,但最有用的实现是使用类似的方法将全局变量设为“私有”。 这样可以避免在定义的范围内对变量进行不必要的修改,但是您需要提供一种从外部修改这些变量的机制。 虽然这样做时需要格外小心。

继续阅读 (To read next)

If you’re an advanced programmer, the semantic of the function above may have resulted familiar to you. It’s because the technique of having a series of nesting function is called a curry in Javascript. If you want to learn more about them, here’s an interesting story:

如果您是高级程序员,那么上面函数的语义可能使您感到熟悉。 这是因为具有一系列嵌套功能的技术在Javascript中称为咖喱 。 如果您想了解更多有关它们的信息,请参考以下有趣的故事:

https://medium.com/better-programming/currying-inside-javascript-a19f29600880

https://medium.com/better-programming/currying-inside-javascript-a19f29600880

翻译自: https://medium.com/weekly-webtips/a-practical-example-of-javascript-closures-d41ce0a7207f

闭包的示例

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值