function foo(a, b){
return a * b;
}
foo(2,3);
ExecutionContext: {}
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: { ... }
}
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
this
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']
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); //43
Angus 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;
})(); //undefined
Smashing: 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();