Level up your JavaScript

Wipe out confusion and become confident

Agenda

  • Function in depth

    Scope, hoisting, closure
  • bind, call, apply

    explicitly set value of this.
  • How JS works

    Stack, Heap, Event loop.
  • Promise

    blocking, non-blocking...
  • this

    De-mystify notorious this
  • Inheritance

    Prototype chain.

Who is this dude?

    • @jsdude005
    • Organize Chicago JavaScript meetup
    • Sr. Web Developer, Nielsen
    • Enjoy Learning, talking about JavaScript

Jump from 14,000ft

Run a Marathon (26.2 miles)

Get 10,000 volt shock

Why Core JavaScript?

You are still coding JavaScript and your friendly framework will not be around forever.

  • You need JavaScript to use the Framework.

    Just only a framework will not a build an application. To put logic, functionalities, you have to use javascript.

  • Magic will through you in trouble.

    Magic is good to do simple things. For large application, magic in frameworks will through you under the bus.

  • Feel why it works not how it works.

    Making things working and understanding .

Function

Create a function


Declaration


function foo(a, b){
    return a * b;
}
          
Expression - anonymous


var foo = function(a, b){
  return a * b;
}
              

Expression - named


var foo = function boo(a, b){
  console.log(boo);
  return a * b;
}
  

var foo = new Function("a", "b", "return a * b;");
          

function in JS



function add(a,b){
  return a + b;
}

console.log(add.length); //2
                  
  1. function like an object

  2. could have property


  3. have a length property

  4. length is number of parameters

function in JS



function add(a,b){
  return a+b;
}
  
console.log(add(2,3));//5
                                              

function noFunc(){
}
  
console.log(noFunc());//undefined
                    
  1. Always return

  2. Default return is undefined


"new" for constructor returns this



function add(a,b){
  return a+b;
}

var b = add(2,3);
console.log(b); //5
                      

function add(a,b){
  return a+b;
}

var b = new add(2,3);
console.log(b); //add{}
                      

function add(a,b){
  this.a = a;
  this.b = b;
  return a+b;
}

var b = new add(2,3);
console.log(b); 
//add{a:2, b:3}
                        

arguments - all the arguments passed to the function



function add(a,b){
  console.log(arguments);
  return a+b;
}
  
add(2,3);
//[2,3]
                        

function add(a,b){
  console.log(arguments);
  return a+b;
}
  
add(2,3,5,7);
//[2,3,5,7]
                        

function add(a,b){
  console.log(arguments);
  return a+b;
}
  
add();
//[]
                          

Function Execution

Two stages.


function foo(a, b){
    return a * b;
}

foo(2,3);
                                    
  • Creation Stage.

  • Execution Stage.

Creation Stage

  • Each function call creates own ExectuionContext

  • Roughly an 'environment' where function executes



Creation stage

create arguments variable


ExecutionContext: {
    scopeChain : { ... },
    variableObject: {
        arguments:{ ... }
    }
}
                      

Set arguments


foo(2,3);
                      

ExecutionContext: {
    scopeChain : { ... },
    variableObject: {
        arguments:{
          0 : 2,
          1 : 3,
          length : 2
        }
    }
}
                                        

Ref: JavaScript execution

variable instantiation


ExecutionContext: {
    scopeChain : { ... },
    variableObject: {
        arguments:{
          0 : 2,
          1 : 3,
          length : 2
        },
        a : 2,
        b : 3
    }
}
                    

function foo(a, b){
    return a * b;
}
foo(2,3);
                    

inner variable, inner function


function foo(a, b){
    
  function inner(){
    console.log(a);
  }

  inner();
  
  var c = a * b;
  return c;
}
                      

inner variable, inner function


function foo(a, b){

  function inner(){
    console.log(c);
  }
  inner();
  
  var c = a * b;
  return c;
}
                            
scanning and adding to the variable object

ExecutionContext: {
  scopeChain : { ... },
  variableObject: {
      arguments:{
        0 : 2,
        1 : 3,
        length : 2
      },
      a : 2,
      b : 3,
      inner : pointer to function inner,
      c : undefined
  }
}
                              

this

object, “owner” of the function being executed


ExecutionContext: {
    scopeChain : { ... },
    variableObject: { ... },
    this:{ ... }
}
                      

ExecutionContext: {
    scopeChain : { ... },
    variableObject: {
        arguments:{
          0 : 2,
          1 : 3,
          length : 2
        },
        a : 2,
        b : 3,
        inner : pointer to function inner(),
        c : undefined,
    },
    this: { ... }
}
                                          

Execution Context and Scope

  • A concept in the language spec

  • Roughly an 'environment' where function executes

  • It holds: scope, scope chain, arguments, variables

  • Each function call creates own ExectuionContext


  • Scope is static

  • Set when function is created and never changes

  • Scope is a property of the function

Execution context is a concept in the language spec that—in layman's terms—roughly equates to the 'environment' a function executes in; that is, variable scope (and the scope chain, variables in closures from outer scopes), function arguments, and the value of the this object.

JavaScript uses static scope; that is, the scope chain of a function is defined at the moment that function is created and never changes; the scope chain is a property of the function.

Execution context is different and separate from the scope chain

Execution stage

  1. Start reading the code from first line

  2. Assign values

  3. If need to access variable, it read from ExecutionContext

  4. Until hits first return or body ends

Summary

  1. Two stages of function: creation, execution

  2. Creates execution context (before running any code)


  3. First thing created is the scope chain

  4. Then it creates variableObject


  5. Create arguments, variable, determine this


  6. Execute function

iPhone

Scope

Scope chain

A collection of

  1. Current execution context

  2. All parent execution context

JavaScript Scope



  • Global scope


  • Local scope


  • Block scope

  • Lexical scope
iPhone

Global...Globe

iPhone
iPhone
iPhone
iPhone
iPhone

Global scope


var a = 2;
function b(){
  console.log(a);
}
                              

Local Scope

iPhone
iPhone

Local/function scope


  1. function call creates execution context (before running any code)

  2. First thing created is the scope chain

  3. Create arguments, variable, determine this

  4. variables and inner functions are available inside only


function usa(){
  var kim = 21;
  console.log(kim);
}
usa(); // 21

console.log(kim); 
//Uncaught ReferenceError: kim is not defined
                                  

JS scope chain
iPhone

Multi execution context


iPhone

var a = 2;

function b(){ 
  console.log(a); 
}

function c(){ 
  console.log(a); 
}

b();
c();
                              

local events

iPhone
iPhone

Block Scope

  1. Block: Anything inside curly braces

  2. Javascript Block statements do not introduce a scope

  3. JavaScript(up to ES5) does not have block scope.

  4. Variables introduced within a block are scoped to the containing function or script



for(var i = 0; i<5; i++){
  var twice = i*2;
}

console.log(i);// 5

console.log(twice);//8

                                

ES6: let and const

  1. let: declares a block scope local variable

  2. Current block and contained sub-blocks

  3. const: can not be reassigned.

  4. const can be recreated inside a loop



  for(let i = 0; i<5; i++){
    const twice = i*2;
  }

  console.log(i);
  //Uncaught ReferenceError: i is not defined
  
  console.log(twice);  
  //Uncaught ReferenceError: twice is not defined
                                  

Closure

iPhone

function in a function



function counter(){
    var i = 0;

    return function(){
        return i++;
    }
}
                                                        

var a = counter();

a;
//function (){
//   return i++;
//}

a(); //0
a(); //1
a(); //2
                                        

Lexical scope/Scope Chain


iPhone

function counter(){
  var i = 0;

  return function(){
      return i++;
  }
}

const a = counter();

a(); // 0
                                  

Lexical Scoping defines how variable names are resolved in nested functions: inner functions contain the scope of parent functions even if the parent function has returned.

Multiple Closure


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

                                          
a and b has separate private i to remember position
iPhone

Multiple Closure

  • Every assignment of counter function creates new closure
  • Private variable

  • Save state

  • Create encapsulation

Who cares?


  1. Garbage collector: can not claim the variable you are holding.

  2. How many closure are you creating?


  3. Variable reference: Don't use excessively large private variable

  4. Unnecessary closure affect processing speed and memory consumption





Closure in Summary


  • function inside another function

  • Doesn't have to return function

  • Refer to variables, parameters outside of current scope

  • Read and write outer scope variable

  • Each closure has separate private variable



Closure for dummies

so far...


  1. function could have properties

  2. Two stages of function call: Creation, Execution


  3. ExecutionContext: Scope chain, variableObj, this

  4. Jackie Chan, Kim Kardashian, super bowl


  5. Scope chain: collection of current + all parent Execution context

  6. Closure: save states and create encapsulation

Hoist a variable



function foo(a, b){
  
  function inner(){
    console.log(a);
  }

  inner();
  
  var c = a * b;
  return c;
}
                                          

ExecutionContext: {
  scopeChain : { ... },
  variableObject: {
      arguments:{
        0 : 2,
        1 : 3,
        length : 2
      },
      a : 2,
      b : 3,
      inner : pointer to function inner,
      c : undefined
  }
}
                                            

Just Looping



function justLooping() {
  
  for (var i = 0; i < 5; i++) {
      var twice = i*2;
  }

  console.log(i);
  console.log(twice);
}

justLooping();// 5 8

                                        

function justLooping() {
  var i;
  var twice;
  
  for (i = 0; i < 5; i++) {
      twice = i*2;
  }
  console.log(i);
  console.log(twice);
}

justLooping(); // 5 8

Hoist function declaration with definition



function outer(){

  inner();
  
  function inner(){
    console.log('inside inner function');
  }  

}

outer();
                                          

function outer(){

  function inner(){
    console.log('inside inner');
  }

  inner();
 
}

outer();  
  

Hoist function name only for function expression



function outer(){
  inner();
  	
  var inner = function(){
    console.log('inside inner');
  }  
}

outer();
//Uncaught TypeError: inner is not a function

                                          

function outer(){
  var inner;
  inner();
  	
  inner = function(){
    console.log('inside inner');
  }  
}

outer();
//Uncaught TypeError: inner is not a function 
  

Million dollar question


var a = 1;

function bar(){
  a = 10;
  return;
  var a = 7;
}

bar();

console.log(a);//?

                                          

function foo(){
  var f = function() {
      console.log("original");
  }

  function f() {
      console.log("duplicate");
  }

  f();
}

foo(); //?
  

Class

Inheritance: in JavaScript

  • JavaScript only has one construct: objects

  • Each object has a private property (referred to as [[Prototype]] )

  • Holds a link to another object called its prototype

  • That prototype object has a prototype of its own
  • Until an object is reached with null as its prototype
  • By definition, null has no prototype, and acts as the final link in this prototype chain

Prototype Chain


var o = object.create(null);


var o = {
  id: 42, 
  name: 'john'
}


function Entity(id, name){
  this.id = id;
  this.name = name;
}
                                          

Using Object (without constructor)


var person = {
  hours: 5,
  getHours: function() {
    return this.hours + 3;
  }
};

person.getHours(); // 8

                                          

var manager = Object.create(person);
// manager is an object that inherits from person

manager.getHours(); //8

// creates an own property 'hours' on manager
manager.hours = 1; 
manager.getHours(); //4


Using constructor


function Person (id, hours) {
  this.id = id;
  this.hours = hours;
  this.getHours = function() {
    return this.id + ' works:' + this.hours +'hr';
  };
}

                                          

function Person (id, hours) {
  this.id = id;
  this.hours = hours;
}

Person.prototype.getHours = function() {
  return this.id + ' works:' + this.hours +'hr';
};
  

Get what is in prototype


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"}
  

this walks through prototype chain.

ES6 - class (syntactical sugar )


function User(name) {
  this.name = name;
}

User.prototype.sayHi = function() {
  return 'Hi '+ this.name;
}


let user = new User("John");
user.sayHi();

                                          

class User {
    constructor(name) {
      this.name = name;
    }
  
    sayHi() {
      return 'Hi ' + this.name;
    }
  }
  
  let user = new User("John");
  user.sayHi();
  

What is this?



console.log(this);//window	

function whatIsThis() {
  return this;
}

whatIsThis(); //window

                                            

function justAddName(name) {
  this.name = name;
  return this;
}

justAddName("Amy Farrah Fowler");//window

console.log(window.name); //Amy Farrah Fowler
    

What is this really?



                                                
(function(){
  console.log(this);
})();
//window


(function(){
    'use strict';
    console.log(this);
})(); 
//undefined
                                                  

Give my this back in strict mode



(function(self){
  'use strict';
  console.log(self);
})(this);
//window


(function(){
  'use strict';
  console.log(this);
}).call(this);
//window
                                                

Spec 10.4.3

this of an Object


var buddy = {
  firstName:'Penny',
  lastName:this.firstName,
  context:this
}
              
buddy.firstName; //Penny
buddy.lastName;//undefined
buddy.context;//window
  

var buddy = {
  firstName:'Penny',
  getName:function(){
    return this.firstName;
  },
  getContext: function() {
    return this;
  }
};

buddy.getName(); //Penny
buddy.getContext(); 
// Object {getContext: function}
MDN: this

Understand the context of execution


var a = {
  b: function() {
      return this;
  }
};

a.b();
//Object {b: function}
  

var foo = a.b;

console.log(foo);
/* function(){
  return this;
};*/

foo(); //window

window.foo(); //window
                                                  

var d = {
  d:'my D'
};

d.c = a.b;

d.c();
//Object {d:'my D', c: function}

Watch left side of dot(.)

Understanding: this

Some more execution context


var a = {
  b: function() {
      var c = function() {
          console.log(this);
      };
      c();
  }
}; 
a.b();//window
  

var a = {
  b: function() {
      (function() {
        console.log(this);
      })();
  }
};

a.b(); //window
                                                  

strict mode will return undefined

context of this

setTimeout inside constructor


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}
  

Same behavior with setInterval

How to fix this?


function Menu(item){
  var that = this;
  this.item = item;
  this.context = this;

  setTimeout(function(){
    console.log('setTimeout context:', that);
  }, 10);

}
              
var lunch = new Menu('pizza');
//setTimeout context: Menu {item: "pizza", context: Menu}

lunch.context;
//Menu {item: "pizza", context: Menu}
  

function Menu(item){
  this.item = item;
  this.context = this;

  setTimeout( () => {
    console.log('setTimeout context:', this);
  }, 10);

}
              
var lunch = new Menu('pizza');
//setTimeout context: Menu {item: "pizza", context: Menu}

lunch.context;
//Menu {item: "pizza", context: Menu}
 

DOM event handler

this = the element that fired the event


//execute it in console
document.getElementById('myButton')
  .addEventListener('click', function(){
    console.log(this);
  });
  

function Bluify(e){
  // Always true
  console.log(this === e.currentTarget); 
  this.style.backgroundColor = 'blue';
}
                                                  
MDN: this

Now. I know this

  1. left of dot(.) will indicate value of this

  2. window (no dot)


  3. undefined (strict mode IIFE)


  4. object (left of dot('.') for a method call)

  5. newly constructed object (constructor: new keyword)


  6. window (inside setTimeout)

  7. element fired the event, inside event handler


  8. use bind, call, apply to set value of this explicitly



JS: execution context

Explicitly set this

bind any function that has this

Create a new function by holding the context(this) to be used later such as dom binding.


function getMonthlyFee(fee){
  var remaining = this.total - fee;
  this.total = remaining;
  return this.name +' remaining balance:' 
         + remaining;
}
  

var rachel = {
  name:'Rachel Green', 
  total:500
};

//bind
var getRachelFee = getMonthlyFee.bind(rachel, 90);

//deduct
getRachelFee();
//Rachel Green remaining balance:410

getRachelFee();
//Rachel Green remaining balance:320
                                                  

bind any method on other object


var monica = {
  name: 'Monica',
  getMonthlyFee:  function(fee){
    var remaining = this.total - fee;
    this.total = remaining;
    return this.name +' remaining balance:' 
         + remaining;
  }
}

  

var ross = {
  name:'Ross Geller', 
  total:250
};

//bind
var getRossFee = monica.getMonthlyFee.bind(ross, 25);

//deduct
getRossFee(); 
//Ross Geller remaining balance:225
getRossFee(); 
//Ross Geller remaining balance:200
                                                  

call and apply

Just use the provided context and execute immediately


function lunch(budget, time){
  return this.menu +' for ' + budget +' within '+ time +' min.';
}

var forDev = {menu: 'pizza'};

lunch.call(forDev, 5, 10);//pizza for 5 within 10 min.
lunch.apply(forDev, [5, 10]);//pizza for 5 within 10 min.
  

this in arguments

8 function allows thisArg


Function.prototype.bind( thisArg [ , arg1 [ , arg2, ... ] ] )
Function.prototype.call( thisArg [ , arg1 [ , arg2, ... ] ] )
Function.prototype.apply( thisArg, argArray )
                                    

Array.prototype.every( callbackfn [ , thisArg ] )
Array.prototype.some( callbackfn [ , thisArg ] )
Array.prototype.forEach( callbackfn [ , thisArg ] )
Array.prototype.map( callbackfn [ , thisArg ] )
Array.prototype.filter( callbackfn [ , thisArg ] )
                                                      

What is JavaScript?

How JavaScript works?

A single-threaded, non-blocking, asnchronous concurrent runtime



I am a programmer, give me detail

Maintain a call stack, event loop, queue, etc.



Are these in JS?

No. They are in JavaScript implementation.


call stack


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);
    
                                              

Call stack





multiply
square
consoleSquare

Stack overflow


function foo(){
  foo();
}    
    
                                              

Call stack


foo
foo
foo
foo
foo
foo
foo
foo
foo
foo
foo
foo
foo
foo
foo

Blocking


  • Blocking methods execute synchronously

  • Non-blocking methods execute asynchronously

  • Does networking or uses timers

  • Usually takes a callback

Async stack


console.log('Hi');

setTimeout(function(){
  console.log('Chicago');
}, 2000)

console.log('There');

// Hi
// There
// Chicago
                                              

Call stack



console.log('There')
???
console.log('Hi')

Concurrency model and Event Loop


  • Stack: frames of call

  • Heap: Objects allocated in teh memory

  • Queue: Runtime list of messages to be processed

  • Event Loop: Check if stack is empty. if empty push anything waiting in the queue

Javascript is single threaded but you have a browser

Events

Event delegate


<ul id="listToDestroy">
  <li><a href="#">first item</a></li>
  <li><a href="#">second item</a></li>
  <li><a href="#">third item</a></li>
  <li><a href="#">forth item</a></li>
  <li><a href="#">Fifth item</a></li>
</ul>
                                                

var el = document.getElementById('listToDestroy');

el.addEventListener('click', function (e) {
    var list = e.target.parentNode;
    list.parentNode.removeChild(list);
    e.preventDefault();
});
        

Event delegate (demo)


<ul id="listToDestroy">
  <li><a href="#">first item</a></li>
  <li><a href="#">second item</a></li>
  <li><a href="#">third item</a></li>
  <li><a href="#">forth item</a></li>
  <li><a href="#">Fifth item</a></li>
</ul>

var el = document.getElementById('listToDestroy');

el.addEventListener('click', function (e) {
    var list = e.target.parentNode;
    list.parentNode.removeChild(list);
    e.preventDefault();
});
        

Promise

iPhone
iPhone
iPhone

Ready to Start?

Start a new journey with confidence.
Be the premium developer. The go to guy.

Block a day

Hands on Learning

The best way to learn is to do it yourself while someone else is there to answer your questions:

WebSlides Files
WebSlides Files

Thanks.

Any question and concern feel free to send me email, set up a time for discussion. one to one training, interview preparation

Best,
@jsdude005,
www.thatJsDude.com,
khan4019@gmail.com.