On Github khan4019 / JSconfusingParts
function foo(a, b){ return a * b; } foo(2,3);
ExecutionContext: {}Each function call creates own ExectuionContext roughly an 'environment' where function executes
ExecutionContext: { scopeChain: { ... } }
ExecutionContext: { scopeChain : { ... }, variableObject: { ... } }
ExecutionContext: { scopeChain : { ... }, variableObject: { arguments:{ ... } } }
ExecutionContext: { scopeChain : { ... }, variableObject: { arguments:{ 0 : 2, 1 : 3, length : 2 } } }
foo(2,3);JavaScript execution
ExecutionContext: { scopeChain : { ... }, variableObject: { arguments:{ 0 : 2, 1 : 3, length : 2 }, a : 2, b : 3 } }
function foo(a, b){ return a * b; } foo(2,3);
function foo(a, b){ function ttt(){console.log(a);} var c = a + b; return a * b; }
ExecutionContext: { scopeChain : { ... }, variableObject: { arguments:{ 0 : 2, 1 : 3, length : 2 }, a : 2, b : 3, ttt : pointer to function ttt(), c : undefined } }
ExecutionContext: { scopeChain : { ... }, variableObject: { ... }, this:{ ... } }
ExecutionContext: { scopeChain : { ... }, variableObject: { arguments:{ 0 : 2, 1 : 3, length : 2 }, a : 2, b : 3, ttt : pointer to function ttt(), c : undefined, }, this: { ... } }
var a = 2; function b(){ console.log(a); }
function b(){ var d = 21; console.log(d); } b();
console.log(d); //ReferenceError: d is not defined
var a = 2; function b(){ console.log(a); } function c(){ console.log(a); } b(); c();
function counter(){ var i = 0; return function(){ return i++; } }
var a = counter(); a; //function (){ // return i++; // }
a();
function counter(){ var i = 0; return function(){ return i++; } }
var a = counter(); a(); //0 a(); //1 a(); //2 a(); //3 a(); //4 a(); //5
var b = counter(); b(); //0 b(); //1 b(); //2 b(); //3
each closure have separate private variable
function foo(a, b){ return arguments; } foo(); //[] foo('js', 'is', 'fun'); //['js', 'is', 'fun']can't explicity created available only when function begin execution arguments & named parameters references same value updateing arguments[i] changes named parameters
arguments.length; //3 arguments[2]; //fun
arguments.indexOf('is'); //TypeError: Object has no method 'indexOf'
var args = Array.prototype.slice.call(arguments); args.map();
function foo(a, arguments) { return arguments; }; foo(1); //undefined
function foo(a, b) { var arguments = 43; return arguments }; foo(1, 2); //43Angus Croll: aguments
function foo(){ console.log(a); //do something var a = 42; }
foo(); //undefined
function foo(){ var a; console.log(a); //do something a = 42; }
function justLooping() { for (var i = 0; i < 5; i++) { //do something } console.log(i); }
function justLooping() { var i; for (i = 0; i < 5; i++) { //do something } console.log(i); }
function outer(){ inner(); //do something else function inner(){ console.log('inside inner function'); } } outer(); // inside inner function
function outer(){ function inner(){ console.log('inside inner'); } //do something inner(); }JS hoisting explained
function outer(){ inner(); //do something else var inner = function(){ console.log('inside inner'); } }
outer();//TypeError: undefined is not a function
function outer(){ var inner; inner(); //do something else inner = function(){ console.log('inside inner'); } }
this;//window
function whatIsThis() { return this; } whatIsThis(); //window
(function(){ return this; })(); //window
(function(){ 'use strict'; return this; })(); //undefinedSmashing: JS Scope
var a = { b: function() { return this; } }; a.b();//Object {b: function}
var foo = a.b;
var foo = function(){ return this; }; foo(); //window
window.foo(); //window
var d = {}; d.c = a.b; d.c();//Object {c: function}Angus Croll: this
function Friend(name) { this.name = name; this.context = this; } var frnd1 = new Friend('js dude'); var frnd2 = new Friend('common guy');
frnd1.name; //js dude frnd1.context;//Friend {name: "js dude", context: Friend}
frnd2.name; //common guy frnd2.context;//Friend {name: "common guy", context: Friend}
var dad = { fathersName:'big Dad' } var child = Object.create(dad);
child.whoIsYourFather = function(){ return this.fathersName; }
child.whoIsYourFather(); //big Dad
child.hasOwnProperty('fathersName'); //false Object.getPrototypeOf(child); //{fathersName: "big Dad"}sitePoint: this
function Menu(item){ this.item = item; this.context = this; setTimeout(function(){ console.log('setTimeout context:', this); }, 10); }
var lunch = new Menu('pizza'); //setTimeout context: window lunch.context//Menu {item: "pizza", context: Menu}
Function.prototype.bind( thisArg [ , arg1 [ , arg2, ... ] ] ) Function.prototype.call( thisArg [ , arg1 [ , arg2, ... ] ] ) Function.prototype.apply( thisArg, argArray )
function bluify(e){ console.log(this === e.currentTarget); // Always true console.log(this === e.target);// true when currentTarget and target are the same object this.style.backgroundColor = '#A5D9F3'; }
//execute it in console document.getElementById('myButton').addEventListener('click', function(){ console.log(this); }, false);
function foo(a){ a = 55; }
var a = 7; foo(a); a; //7
function foo(speaker){ speaker.name = 'Paul Irish'; } var speaker = {name : 'Addy Osmani'}; foo(speaker); console.log(speaker);//Object {name : "Paul Irish"}
function foo(speaker){ speaker = {name : 'Paul Irish'}; } var speaker = {name : 'Addy Osmani'}; foo(speaker); console.log(speaker);//Object {name : "Addy Osmani"}
function multiply(a,b){ return a * b; } function square (n){ return multiply(n,n); } function consoleSquare(n){ var squared = square(n); console.log(squared); }
consoleSquare(3);js strack trace
foo(); //window.foo();
a.b();