Home  >  Article  >  Web Front-end  >  How to Overcome Closure Pollution in Loops: A Practical Guide

How to Overcome Closure Pollution in Loops: A Practical Guide

Mary-Kate Olsen
Mary-Kate OlsenOriginal
2024-10-16 17:50:02636browse

How to Overcome Closure Pollution in Loops: A Practical Guide

Closures Inside Loops: A Practical Guide to Resolving Closure Pollution

In programming, closures play a crucial role in capturing variables from outer scopes. However, when used within loops, they can lead to unexpected results known as closure pollution. This article explores this problem and provides practical solutions to resolve it.

The Problem

Consider the following code:

<code class="javascript">var funcs = [];

for (var i = 0; i < 3; i++) {
  funcs[i] = function() {
    console.log("My value:", i);
  };
}

for (var j = 0; j < 3; j++) {
  funcs[j]();
}</code>

Unfortunately, this code outputs:

<code>My value: 3
My value: 3
My value: 3</code>

rather than:

<code>My value: 0
My value: 1
My value: 2</code>

The Issue

The problem arises because each function declared within the loop captures the same i variable from the outer scope. When the functions are invoked within the second loop, they all reference the same i, which has been incremented to 3 by the time they are executed.

ES6 Solution: let

ES6 introduced the let keyword, which creates block-scoped variables. Using let within the loop ensures that each iteration has its own distinct i variable, resolving the closure pollution issue:

<code class="javascript">for (let i = 0; i < 3; i++) {
  funcs[i] = function() {
    console.log("My value:", i);
  };
}</code>

ES5.1 Solution: forEach

Another solution for arrays is to use the forEach method:

<code class="javascript">var someArray = [/* values */];

someArray.forEach(function(element) {
  // ...code specific to this element...
});</code>

Each iteration of the forEach loop creates its own closure, capturing the array element specific to that iteration.

Classic Solution: Closures

The classic solution involves manually binding the variable to a separate, unchanging value outside of the function:

<code class="javascript">var funcs = [];

function createFunc(i) {
  return function() {
    console.log("My value:", i);
  };
}

for (var i = 0; i < 3; i++) {
  funcs[i] = createFunc(i);
}

for (var j = 0; j < 3; j++) {
  funcs[j]();
}</code>

By passing the i variable as an argument to the inner function, we create a new closure for each iteration, ensuring that each function references its own independent value.

The above is the detailed content of How to Overcome Closure Pollution in Loops: A Practical Guide. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn