JavaScript loop variable scope
See the MDN for the "initialization parameters" of a for
-loop:
An expression (including assignment expressions) or variable declaration. Typically used to initialize a counter variable. This expression may optionally declare new variables with the var keyword. These variables are not local to the loop, i.e. they are in the same scope the for loop is in. The result of this expression is discarded.
JavaScript: Understanding let scope inside for loop
General Explanation
When you use let
in the for
loop construct like you show, there is a new variable i
created for each invocation of the loop that is scoped just to the block of the loop (not accessible outside the loop).
The first iteration of the loop gets its value from the for
loop initializer (i = 1
in your example). The other new i
variables that are created each loop iteration get their value from the i
for the previous invocation of the loop, not from the i = 1
which is why they aren't all initialized to 1
.
So, each time through the loop there is a new variable i
that is separate from all the other ones and each new one is initialized with the value of the previous one and then processed by the i++
in the for
loop declaration.
For your ES6 code of this:
for(let i = 1; i <= 5; i++) { setTimeout(function(){ console.log(i); },100);}
Javascript for-loop variable scope?
Before ECMAScript 6, javascript only supports function scoping. A variable declared inside a function is visible anywhere inside that function. Even this:
function foo() { if(true) { if(true) { var v = 7; } }
console.log(v); // 7}foo();
JS loop variable scope
Yes. Functions are the only possibility to introduce a new scope in JavaScript (though that might change in future versions withWe can achieve such behavior by creating explicit function scope. But is it the standard way / followed in production?
let
); and IIFEs are heavily used in production as well.To limit the scope ofWhat other things can be done?
i
to the for-loop's block? None (let alone let
). However, you hardly will need to do that, since nothing will interfere with it - var i
is still scoped local to your function. Sometimes, you even might want to use i
after the loop as an ongoing counter. Variable scope in Javascript for loop
The first example will either add or modify the global variable x, which is generally to be avoided if not the desired outcome.
While your second example works as desired (no side effects) an alternative that looks better in my opinion would be
function bar()
{
for (var x=0; x< 100; x++) {}
}
Context and variable scope in ES6 loops and forEach
Regular functions use execution context to set the value of this
, meaning that in in most cases, the value of this
is determined by how a function is called, i.e. the value of this
is set according to the environment in which the function is executed.
Arrow functions do not have their own this
value, instead they use lexical scoping, meaning the value of this
inside an arrow function is always inherited from the enclosing scope, i.e. it is set to the this
value of the enclosing execution context.
This is explained in the documentation as well
The third example posted is just a regularUntil arrow functions, every new function defined its own
this
value
(a new object in case of a constructor, undefined in strict mode
function calls, the context object if the function is called as an
"object method", etc.). This proved to be annoying with an
object-oriented style of programming.
....
Arrow functions capture the this value of the enclosing context
for
loop, and has very little in common with functions, and can't really be compared to the two first code examples.for
loops work the same in ES2015 as they always have, there generally is no special scope in for
loops for variables, as variables (defined with var
) are function scoped.However, ES2015 does introduce variables that can are block scoped as wel, and as a for
loop is in fact a block (for (what) {block}
), those variables can be used, and they are defined with either the let
keyword, or the const
keyword for a constant (that can not be changed) .
For those that prefer code
var o = {
nums : [1,2,3,4],
fn : function() {
var self = this;
this.nums.forEach(function(v) {
// "this" in this context would be the window,
// but "self" would be the object "o", hence the common use of this hack
});
this.nums.forEach((v) => {
// "this" in this context, would be the object "o"
// that happens because the "this-value" in the fn() function,
// ... is the parent object
// and the arrow function inherits that this-value
});
for (var i=0; i<this.nums.length; i++) {
// "this" in this context is what it has always been,
// a for-loop has the same this-value as the surrounding scope
}
}
}
o.fn(); // called from global context "window"
Related Topics
Get Selected HTML in Browser via JavaScript
Detect Whether Scroll Event Was Created by User
Fix the Upstream Dependency Conflict Installing Npm Packages
Understanding JavaScript Promise Object
How to Send Data in Request Body with a Get When Using Jquery $.Ajax()
Jquery Document.Ready VS Phonegap Deviceready
What Are Some Empirical Technical Reasons Not to Use Jquery
How to Initialize a JavaScript Date to Midnight
Accessing JSON Object Keys Having Spaces
How to Take Advantage of Callback Functions for Asynchronous Xmlhttprequest
Do Websockets Allow for P2P (Browser to Browser) Communication
Intercept Paste Event in JavaScript
Why Do People Put Code Like "Throw 1; <Dont Be Evil>" and "For(;;);" in Front of JSON Responses
Splicing a JavaScript Array from Within the Callback Passed to Foreach
Pass Post Data with Window.Location.Href
How to Sort an Associative Array by Its Values in JavaScript