http://attheo.do
Node.js meetup
Once and for all, hopefully
When a variable appears on the lefthand side of an assignment operation.
When a variable appears on the righthand side of an assignment operation.
Simply "Not lefthand side"
Scope resolution FAILED
function lala(a) {
console.log(a); // 2
}
lala(2);
RHS
LHS
RHS
LHS/RHS
Think like those guys!
}
function lala(a) {
console.log(a); // 2
}
lala(2);
"Hey Scope, ever heard of lala?"
"Yup, Compiler declared it. It's function. Take it"
"Hey Scope, I have an LHS for a, know it?"
"Compiler says it's a parameter to lala, here you go"
"Thanks Scope, please assign 2 to a"
"Hey Scope, me again. Need an RHS for console. Know it?"
"Yup, built-in shit. Take it."
"Yo Scope. Need RHS to a, remember anything?"
function lala(a) {
console.log(a+b);
}
var b = 2;
lala(2);
"Hey Scope of lala, got an RHS for b"
"Fuck off Engine, know nuthin' "
"Hey outer scope, oh you're the global Scope! Need an RHS for b, know anything?"
"Sure thing dawg. Here ya go"
Global Scope
Current Scope
Lexical Scope(s)
Global Scope
Foo Scope
Bar Scope
Scope "bubbles" are strictly nested.
Scope lookup stops once it finds the first match!
eval()
with
function foo(a) {
var b = 2;
// some shit..
function bar() {
// some other shit...
}
// oh, look a turd!
var c = 3;
}
bar(); // Fails
console.log(a, b, c); // Fails
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;
function doSomethingElse(a) {
return a - 1;
}
b = a + doSomethingElse(a*2);
console.log(b*3);
}
doSomething(2); // 15
var a = 2;
function foo() { ///// <--- we add this...
var a = 3;
console.log(a); // 3
}
foo(); ////// <---- And this...
console.log(a); // 2
var a = 2;
(function IIFE(global) {
var = 3;
console.log(a); // 3
console.log(global.a); // 2
}) (window);
console.log(a); // 2
{
try {
throw undefined;
} catch(a) {
a = 2;
console.log(a);
}
}
console.log(a); // Fails
{
let a = 2;
console.log(a); // 2
}
console.log(a); // ReferenceError
a = 2;
var a;
console.log(a);
/**** DIFFERENT CONTEXT ****/
console.log(a);
var a = 2;
WTF?!
var a=2;
{
var a;
a = 2;
Declaration!
Assignment
var a;
a = 2;
console.log(a);
/**** DIFFERENT CONTEXT ****/
var a;
console.log(a);
a = 2;
foo();
function foo() {
console.log(a); // undefined
var a = 2;
}
foo(); // TypeError! (Not ReferenceError)
var foo = function bar() {
console.log(a); // undefined
var a = 2;
}
foo(); // 1
var foo;
function foo() {
console.log(1);
}
foo = function() {
console.log(2);
};
function foo() {
console.log(1);
}
// var foo; was ignored
foo(); // 1
foo = function() {
console.log(2);
}
function foo() {
var a = 2;
function bar() {
console.log(a);
}
return bar;
}
var lala = foo();
lala(); // 2.. Wow so much closure!
function foo() {
var a = 2;
function baz() {
console.log(a); // 2
}
bar(baz);
}
function bar(fn) {
fn();
}
for (var i = 1; i <= 5; i++) {
setTimeout( function timer() {
console.log(i);
}, i * 1000);
}
for (var i = 1; i <= 5; i++) {
(function() {
var j = i;
setTimeout(function timer() {
console.log(j);
}, j*1000);
})();
}
var foo = (function MyModule() {
var something = 'cool';
var somethingElse = [1, 2, 3];
function doSomething() {
console.log(something);
}
function doAnother() {
console.log( somethingElse.join(" ! "));
}
return {
doSomething: doSomething,
doAnother: doAnother
};
})();
foo.doSomething(); // cool
foo.doAnother(); // 1 ! 2 ! 3