Skip to content

Instantly share code, notes, and snippets.

Created December 28, 2012 16:54
Show Gist options
  • Save anonymous/4399644 to your computer and use it in GitHub Desktop.
Save anonymous/4399644 to your computer and use it in GitHub Desktop.
Scoping and variable hoisting are two of the most challenging subjects to learn when picking up javascript, because it is fundamentally different from the other C-like languages' behavior. Javascript, unlike C and others, creates a new variables scope for each CLOSURE created, not for each BLOCK. This leads to some confusion in some cases. Here'…
// Source and Commented code:
// https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/forEach
if ( !Array.prototype.forEach ) {
Array.prototype.forEach = function forEach( callback, thisArg ) {
var T, k;
if ( this == null ) {
throw new TypeError( "this is null or not defined" );
}
var O = Object(this);
var len = O.length >>> 0;
if ( {}.toString.call(callback) !== "[object Function]" ) {
throw new TypeError( callback + " is not a function" );
}
if ( thisArg ) {
T = thisArg;
}
k = 0;
while( k < len ) {
var kValue;
if ( Object.prototype.hasOwnProperty.call(O, k) ) {
kValue = O[ k ];
callback.call( T, kValue, k, O );
}
k++;
}
};
}
var array = ["zero","first","second","third","fourth","fifth"];
var closures = [];
for(var i=0, l=array.length; i<l; i++)(function(item, i){
closures.push(function(){return item});
})(array[i],i);
closures[3]();
// Actually returns "third", because functions create new scopes,
// so on each iteration of the 'for' loop the variable 'i' gets binded
// on the first closure to the current value, and on the second inner
// function the value is the one expected in the first place.
var array = ["zero","first","second","third","fourth","fifth"];
var closures = [];
array.forEach(function(item, i){
closures.push(function(){return item});
});
closures[3]();
// Returns "third" as expected.
// Since 'Array.forEach()' receives a function it already creates
// a new scope for each iteration.
var array = ["zero","first","second","third","fourth","fifth"];
var closures = [];
for(var i=0, l=array.length; i<l; i++){
closures.push(function(){return array[i]});
}
closures[3]();
// Expected "third", but actually returns 'undefined',
// because js did not create a separate scope for the "for" block
// and the variable 'i' ended up with a value '6' for all
// functions created in the loop, and 'array[6]' is not defined.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment