var a = 2;
{
"type": "VariableDeclaration",
"declarations": [
{
"type": "VariableDeclarator",
"id": {
"type": "Identifier",
"name": "a"
},
"init": {
"type": "Literal",
"value": 2,
"raw": "2"
}
}
],
"kind": "var"
}
Keyword
Identifyer
Punctuator
Punctuator
Numeric
var a = 2;
1. Compiler tokenize / lex > parse to AST > generate code:
- @ "var a" ask Scope if "a" already exist for current scope
- if exist, C ignore statement and moves on
- else C ask Scope to declare "a" for current scope
2. Engine execute code:
- @ "a = 2" ask Scope for "a" in current scope
- if exist, assign to it
- else if found in nested scope, assign to it
- else throw error
function foo(a) {
var b = a * 2;
function bar(c) {
console.log(a, b, c);
}
bar(b * 3);
}
foo(2); // 2, 4, 12
function foo(a) {
var b = a * 2;
function bar(c) {
var b = c;
}
bar(b * 3);
}
foo(2);
function foo(a) {
var b = a * 2;
function bar(c) {
var b = c; // "shadowing"
}
bar(b * 3);
}
foo(2);
function foo(a) {
b = a * 2;
}
foo(2);
console.log(b);
function foo(a) {
var b = a * 2;
}
foo(2);
console.log(b);
function foo(a) {
"use strict";
b = a * 2;
}
foo(2);
function foo(a) {
b = a * 2;
}
foo(2);
console.log(b); // 4
function foo(a) {
var b = a * 2;
}
foo(2);
console.log(b); // ReferenceError: b is not defined
function foo(a) {
"use strict";
b = a * 2;
}
foo(2); // ReferenceError: b is not defined
function foo(str, a) {
eval( str );
console.log( a, b );
}
var b = 2;
foo( "var b = 3;", 1 ); // ?
function foo(str, a) {
eval( str ); // cheating!
console.log( a, b );
}
var b = 2;
foo( "var b = 3;", 1 ); // 1, 3
function foo(str) {
"use strict";
eval( str );
console.log( a ); // ?
}
foo( "var a = 2" );
function foo(str) {
"use strict";
eval( str );
console.log( a ); // ReferenceError
}
foo( "var a = 2" );
function foo(obj) {
with (obj) {
a = 2;
}
}
var o1 = { a: 3 };
var o2 = { b: 3 };
foo( o1 );
console.log( o1.a ); // ?
foo( o2 );
console.log( o2.a ); // ?
console.log( a ); // ?
function foo(obj) {
with (obj) {
a = 2;
}
}
var o1 = { a: 3 };
var o2 = { b: 3 };
foo( o1 );
console.log( o1.a ); // 2
foo( o2 );
console.log( o2.a ); // ?
console.log( a ); // ?
function foo(obj) {
with (obj) {
a = 2;
}
}
var o1 = { a: 3 };
var o2 = { b: 3 };
foo( o1 );
console.log( o1.a ); // 2
foo( o2 );
console.log( o2.a ); // undefined
console.log( a ); // ?
function foo(obj) {
with (obj) {
a = 2;
}
}
var o1 = { a: 3 };
var o2 = { b: 3 };
foo( o1 );
console.log( o1.a ); // 2
foo( o2 );
console.log( o2.a ); // undefined
console.log( a ); // 2 - leaked global!
function foo(obj) {
"use strict";
with (obj) {
a = 2;
}
}
var o1 = { a: 3 };
var o2 = { b: 3 };
foo( o1 );
console.log( o1.a ); // 2
foo( o2 );
console.log( o2.a ); // undefined
console.log( a ); // 2 - leaked global!
function foo(obj) {
"use strict";
with (obj) { // SyntaxError: Strict mode code
a = 2; // may not include a with statement
}
}
var o1 = { a: 3 };
var o2 = { b: 3 };
foo( o1 );
console.log( o1.a ); // 2
foo( o2 );
console.log( o2.a ); // undefined
console.log( a ); // 2 - leaked global!
function doSomething(a) {
b = a + doSomethingElse( a * 2 );
console.log( b * 3 );
}
function doSomethingElse(a) {
return a - 1;
}
var b;
doSomething( 2 ); // 15
function doSomething(a) {
var b = a + doSomethingElse( a * 2 );
console.log( b * 3 );
}
function doSomethingElse(a) {
return a - 1;
}
doSomething( 2 ); // 15
function doSomething(a) {
function doSomethingElse(a) {
return a - 1;
}
var b = a + doSomethingElse( a * 2 );
console.log( b * 3 );
}
doSomething( 2 ); // 15
function foo() {
function bar(a) {
i = 3;
console.log( a + i );
}
for (var i = 0; i < 10; i++) {
bar( i * 2 );
}
}
foo();
function foo() {
function bar(a) {
i = 3; // changes i in containing scope
console.log( a + i );
}
for (var i = 0; i < 10; i++) {
bar( i * 2 ); // infinite loop
}
}
foo();
var MyNamespace = {
awesome: "stuff",
doSomething: function() {
// ...
},
doAnotherThing: function() {
// ...
}
};
var a = 2;
function foo() {
var a = 3;
console.log( a ); // 3
}
foo();
console.log( a ); // 2
var a = 2;
(function IIFE() {
var a = 3;
console.log( a ); // 3
})();
console.log( a ); // 2
var a = 2;
(function IIFE( global ) {
var a = 3;
console.log( global.a ); // 2
})( window );
console.log( a ); // 2
var a = 2;
(function IIFE( $ ) {
var a = 3;
console.log( a ); // 3
})( jQuery );
console.log( a ); // 2
var undefined = true;
(function IIFE( undefined ) {
console.log( undefined ); // undefined
})();
console.log( undefined ); // true
var a = 2;
(function IIFE( def ) {
def ( window );
})(function def( global ){
var a = 3;
console.log( a ); // 3
console.log( global.a ); // 2
});
setTimeout(function() {
console.log("Anonymous");
}, 1);
setTimeout(function timeoutHandler() {
console.log("Named");
}, 1);
function clickHandler(evt) {
evt.preventDefault();
this.removeEventListener("click", clickHandler)
}
el.addEventListener("click", clickHandler);
Examples:
for (var i = 0; i < 3; i++) {
console.log(i);
}
console.log(i); // ?
var foo = true;
var radius = 3;
if (foo) {
var pi = 3.1415;
foo = pi * radius * radius;
}
console.log(pi); // ?
var objects = [{}, {} ,{}];
for (var i = 0; i < objects.length; i++) {
objects[i].click = function() {
console.log(i);
};
}
objects.forEach(function(obj) {
obj.click(); // ?
});
try {
console.debag();
} catch (e) {
var b = e.message;
}
console.log(b); // ?
try {
console.debag();
} catch (e) {
var b = e.message;
}
console.log(b); // ReferenceError
function process(data) {
// do something interesting
}
var someReallyBigData = { .. };
process(someReallyBigData);
var btn = document.getElementById("my_button");
btn.addEventListener("click", function click(evt) {
console.log("button clicked");
});
function process(data) {
// do something interesting
}
{
let someReallyBigData = { .. };
process(someReallyBigData);
}
var btn = document.getElementById("my_button");
btn.addEventListener("click", function click(evt) {
console.log("button clicked");
});
var foo = true;
if (foo) {
let bar = foo * 2;
bar = something( bar );
console.log( bar );
}
console.log( bar ); // ReferenceError
for (let i = 0; i < 10; i++) {
console.log( i );
}
console.log( i ); // ReferenceError
var foo = true;
if (foo) {
var a = 2;
const b = 3; // block-scoped to the containing `if`
a = 3; // just fine!
b = 4; // error!
}
console.log( a ); // 3
console.log( b ); // ReferenceError!
a = 2;
var a;
console.log( a ); // ?
a = 2;
var a;
console.log( a ); // 2
console.log( a ); // ?
var a = 2;
console.log( a ); // undefined
var a = 2;
a = 2;
var a;
console.log( a );
//---------- Compilation
var a;
//---------- Execution
a = 2;
console.log( a );
console.log( a );
var a = 2;
//---------- Compilation
var a;
//---------- Execution
console.log( a );
a = 2;
foo();
function foo() {
console.log( a );
var a = 2;
}
//---------- Compilation
function foo() {
var a;
}
//---------- Execution
foo();
//------ in scope foo
console.log( a ); // undefined
a = 2;
foo(); // ?
bar(); // ?
var foo = function bar() {
// ...
};
foo(); // TypeError
bar(); // ReferenceError
var foo = function bar() {
// ...
};
//---------- Compilation
var foo;
//---------- Execution
foo(); // TypeError
bar(); // ReferenceError
foo = function() {
var bar = __self__;
};
foo(); // ?
var foo;
function foo() {
console.log( 1 );
}
foo = function() {
console.log( 2 );
};
foo(); // 1
var foo;
function foo() {
console.log( 1 );
}
foo = function() {
console.log( 2 );
};
//-------- Compilation
function foo() {
console.log( 1 );
}
//-------- Execution
foo(); // 1
foo = function() {
console.log( 2 );
};
foo(); // ?
function foo() {
console.log( 1 );
}
var foo = function() {
console.log( 2 );
};
function foo() {
console.log( 3 );
}
foo(); // 3
function foo() {
console.log( 1 );
}
var foo = function() {
console.log( 2 );
};
function foo() {
console.log( 3 );
}
//------- Compilation
function foo() {
console.log( 3 );
}
//------- Execution
foo();
var foo = function() {
console.log( 2 );
};
foo(); // ?
var a = true;
if (a) {
function foo() { console.log( "a" ); }
}
else {
function foo() { console.log( "b" ); }
}
foo(); // "b"
var a = true;
if (a) {
function foo() { console.log( "a" ); }
}
else {
function foo() { console.log( "b" ); }
}
//------ Compilation
function foo() { console.log( "b" ); }
var a;
//------ Execution
foo(); // "b"
a = true;
if (a) {
//...
}
else {
//...
}
function foo() {
var a = 2;
function bar() {
console.log( a ); // 2
}
bar();
}
foo();
function foo() {
var a = 2;
function bar() {
console.log( a );
}
return bar;
}
var baz = foo();
baz();
function foo() {
var a = 2;
function baz() {
console.log( a ); // 2
}
bar( baz );
}
function bar(fn) {
fn();
}
var fn;
function foo() {
var a = 2;
function baz() {
console.log( a );
}
fn = baz;
}
function bar() {
fn();
}
foo();
bar();
function wait(message) {
setTimeout(function timer(){
console.log( message );
}, 1000);
}
wait( "Hello, closure!" );
function setupRobot(name, selector) {
$(selector).click(function activator() {
console.log( "Activating: " + name );
});
}
setupRobot( "Closure Bot 1", "#bot_1" );
setupRobot( "Closure Bot 2", "#bot_2" );
var a = 2;
(function IIFE(){
console.log( a );
})();
for (var i = 1; i <= 5; i++) {
setTimeout(function timer() {
console.log( i );
}, i * 1000);
}
// ?
for (var i = 1; i <= 5; i++) {
setTimeout(function timer() {
console.log( i );
}, i * 1000);
}
// 6, 6, 6, 6, 6
for (var i = 1; i <= 5; i++) {
(function() {
setTimeout(function timer() {
console.log( i );
}, i * 1000 );
})();
}
// ?
for (var i = 1; i <= 5; i++) {
(function() {
setTimeout(function timer() {
console.log( i );
}, i * 1000 );
})();
}
// ?
for (var i = 1; i <= 5; i++) {
(function() {
setTimeout(function timer() {
console.log( i );
}, i * 1000 );
})();
}
// 6, 6, 6, 6, 6
for (var i = 1; i <= 5; i++) {
(function() {
var j = i;
setTimeout(function timer() {
console.log( j );
}, j * 1000 );
})();
}
// 1, 2, 3, 4, 5
for (var i = 1; i <= 5; i++) {
(function(j) {
setTimeout(function timer() {
console.log( j );
}, j * 1000 );
})(i);
}
// 1, 2, 3, 4, 5
for (var i = 1; i <= 5; i++) {
let j = i;
setTimeout(function timer() {
console.log( j );
}, j * 1000);
}
for (let i = 1; i <= 5; i++) {
setTimeout(function timer() {
console.log( i );
}, i * 1000);
}
function foo() {
var something = "We ahead";
var another = [24, 7];
function doSomething() {
console.log( something );
}
function doAnother() {
console.log( another.join( "/" ) );
}
}
function Module() {
var something = "We ahead";
var another = [24, 7];
function doSomething() {
console.log( something );
}
function doAnother() {
console.log( another.join( "/" ) );
}
return {
doSomething: doSomething,
doAnother: doAnother
};
}
var foo = Module();
foo.doSomething(); // "We ahead"
foo.doAnother(); // "24/7"
var foo = (function Module() {
var something = "We ahead";
var another = [24, 7];
function doSomething() {
console.log( something );
}
function doAnother() {
console.log( another.join( "/" ) );
}
return {
doSomething: doSomething,
doAnother: doAnother
};
})()
foo.doSomething(); // "We ahead"
foo.doAnother(); // "24/7"
function Factory(id) {
function identify() {
console.log( id );
}
return {
identify: identify
};
}
var foo1 = Factory( "andolf" );
var foo2 = Factory( "lååpez" );
foo1.identify(); // "andolf"
foo2.identify(); // "lååpez"
var foo = (function Factory(id) {
function identify() {
console.log( id );
}
function identify2() {
console.log( id.toUpperCase() );
}
function change() {
// modifying the public API
publicAPI.identify = identify2;
}
var publicAPI = {
change: change,
identify: identify
};
return publicAPI;
})( "andolf" );
foo.identify(); // "andolf"
foo.change();
foo.identify(); // "ANDOLF"
var Manager = (function Manager() {
var modules = {};
function define(name, dependencies, func) {
var length = dependencies.length,
i = 0;
for (; i < length; i++) {
dependencies[i] = modules[dependencies[i]];
}
modules[name] = func.apply( func, dependencies );
}
function require(name) {
return modules[name];
}
return {
define: define,
require: require
};
})();
Manager.define("foo", [], function() {
return {
sayHi: function() {
return "Hi";
}
};
});
Manager.define("bar", ["foo"], function(foo) {
return {
log: function() {
console.log(foo.sayHi());
}
};
});
var baz = Manager.require("bar");
baz.log(); // "Hi"
// foo.js
function sayHi() {
return "Hi";
}
export sayHi;
// bar.js
// import only `sayHi()` from the "foo" module
import sayHi from "foo";
function log() {
console.log( sayHi() );
}
export log;
// main.js
// import the entire "bar" module
module bar from "bar";
bar.log(); // "Hi"
Responsible for storing variables in some location and for retrieving those variables at a later time
Store variable at lex-time in current scope. Retrieve variable from current scope or enclosing scope(s)