http://slides.com/halahsalih-1/scope-and-closures
To understand how scope works, we need to understand how Javascript engine does its magic.
var x = 10;
Tokenizing/Lexing
breaking series of characters into meaningful chunks of code. "Tokens"
1
Parsing
taking an array of tokens and turning them into tree of nested elements.
Trees called Abstract Syntax trees
Code-Generation
Taking AST and turing them into machine instructions.
2
3
var x = 10;
tokenizing
tokens = [var,x,=,10,;]
parsing
AST
variable declaration
identifier assignment expression
x numerical literal
10
Engine
responsible for compilation and execution of javascript
Compiler
parsing and code-generation
Scope
creating and maintaining 'look up' table/list of all declared identifiers and has a set of rules for how these identifiers are accessible to the current executable code.
var x = 10;
In a browser environment, the Window is considered the global scope.
// x is a globally scoped variable
var x = 10;
function f1(){
console.log(x ,' can be accessed inside f1');
}
console.log(x, ' accessed outside functions');
f1();
function f2(){
console.log(x ,' can be accessed inside f2 too');
}
f2();//globally scoped variable
var x = 10;
function f3(){
//local scope variable
var x = 5;
console.log(x);
}
f3();Till ES6, There is no block level scoping in Javascript. ES6 support block level scoping using the keywords let, const
function f4(){
if(true){
var a = 'yo';
}
console.log(a);
for(var b = 0; b < 3; b++){
}
console.log(b);
}
f4();function f5(){
if(true){
let a = 'yo';
}
console.log(a);
}
f5();var x = 10;
console.log(x);
try {
throw 7;
} catch (b) {
console.log(b);
}
console.log(x);
console.log(b);foo( 2 );
function foo(a) {
console.log( a + b );
}
var b = 2;function foo(a) {
console.log( a + b );
}
var b = 2;
foo( 2 );
function f9(){
var a = 10;
function f9_1(){
var b = 2;
console.log(a);
function f9_1_1(){
console.log(b);
}
f9_1_1();
}
f9_1();
}
f9();var x = 10;
(function () {
console.log(x);
var x = 5;
console.log(x);
})();
//what is the output?
// why?
var name1 = "Dany";
(function () {
console.log("Original name was " + name1);
var name1 = "Tyrion";
console.log("New name is " + name1);
})();amIHoisted();
function amIHoisted() {
console.log("Yes, I'm hoisted");
}function f1(){
function f2() {
return 'first f2';
}
return f2();
function f2() {
return 'second f2';
}
}
console.log(f1());function f1(){
function f2() {
return 'first f2';
}
return f2();
function f2() {
return 'second f2';
}
}
console.log(f1());function f1(){
var f2 = function() {
return 'first f2';
}
return f2();
var f2 = function() {
return 'second f2';
}
}
console.log(f1());function f1(){
var f2 = function() {
return 'first f2';
};
return f2();
var f2 = function() {
return 'second f2';
};
}
console.log(f1());setTimeout(function(){
console.log('just waited a whole second over here');
}, 1000);(function(){
console.log('yo, just invoked');
})();Closure is when a function is able to remember and access its lexical scope even when that function is executing outside its lexical scope. "
function f1() {
var x = 10;
function f2() {
console.log( x );
}
return f2;
}
var f3 = f1();
f3();var fn;
function f1() {
var x = 10;
function f2() {
console.log( x );
}
fn = f2;
}
function f3() {
fn();
}
f1();
f3();
function wait(message) {
setTimeout( function t(){
console.log( message );
}, 1000 );
}
wait( "Yo, closure alert!" );for (var i=1; i<=3; i++) {
setTimeout( function timer(){
console.log( i );
}, i*1000 );
}for (var i=1; i<=3; i++) {
(function(){
setTimeout( function timer(){
console.log( i );
}, i*1000 );
})();
}for (var i=1; i<=3; i++) {
(function(j){
setTimeout( function timer(){
console.log( j );
}, j*1000 );
})( i );
}for (let i=1; i<=3; i++) {
setTimeout( function timer(){
console.log( i );
}, i*1000 );
}Twitter:HalinaSalih
Github:HalahRaadSalih
email:halah.alshaikhly@gmail.com