Created
December 28, 2012 16:54
-
-
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'…
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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++; | |
} | |
}; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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