JavaScript 102

Web Programming Course

SUT • Fall 2018

TOC

  • Coercion
  • Context
  • "use strict";
  • Event Loop
  • Closure
  • Execution Context
  • IIFE
  • Inheritance

Coercion

More on FreeCodeCamp & 2ality

String(5)        //-> "5"
String(true)

Number('5')      //-> 5
Number(false)    //-> 0

Boolean('')      //-> false
Boolean('false') //-> true

Explicit Coercion

Type Conversion

  • To String
  • To Number
  • To Boolean

Coercion

More on FreeCodeCamp & 2ality

'' + 5           //-> "5"
false + '1'      //-> "false1"

+'5'             //-> 5
0 + '5'          //-> 5
false * 1        //-> 0

Boolean('')      //-> false
Boolean('false') //-> true

if (2) { ... }   // truthy condition
!!2              //-> true
2 || 'hello'     //-> 2

Implicit Coercion

Type Conversion

  • To String
  • To Number
  • To Boolean

Coercion

More on FreeCodeCamp & 2ality

[] + {}  //-> '[object Object]'
{} + []  //-> 0

0 && 'y'         //-> 0
1 && false       //-> false

'true' == true   //-> false
false == 'false' //-> false
null == ''       //-> false

Implicit

(Implicit) coercion seems hacky when it comes to:

Coercion

More on FreeCodeCamp & 2ality

Object Type Coercion

[[ToPrimitive]]

 

The optional parameter PreferredType is either Number or String.

  1. If the input is primitive, return it as is.
  2. Otherwise, the input is an object. Call obj.valueOf(). If the result is primitive, return it.
  3. Otherwise, call obj.toString(). If the result is a primitive, return it.
  4. Otherwise, throw a TypeError.

 

If PreferredType is String, steps 2 and 3 are swapped. If PreferredType is missing then it is set to String for instances of Date and to Number for all other values.

ToPrimitive(input, PreferredType?)

Coercion

More on FreeCodeCamp & 2ality

Examples

[] + {}  //-> '[object Object]'
{} + []  //-> 0

// Can you explain?

Context

The this keyword

More on MDN

var test = {
  prop: 42,
  func: function() {
    return this.prop;
  },
};

test.func();
//-> 42

The value of this is (almost) determined by how a function is called.

Context

  • Global Context

 

 

 

  • Function Context

More on MDN

// In web browsers, the window object
// is also the global object:
console.log(this === window); // true
function f1() {
  return this;
}
// in non-strict mode
f1() === window; // true

f1.call('my ctx');  //-> 'my ctx'
f1.apply('my ctx'); //-> 'my ctx'
// .bind() returns a new function
// that when called has its 'this'
// set to the provided value
f1.bind('my ctx');
  • Simple call with ()
  • .call(), .apply() and .bind() methods
  • As an object method
  • with new keyword

Context

Example

More on MDN

"use strict";

  • Get rid of some JavaScript silent errors
  • Let JavaScript engines perform optimizations
  • ...

More on MDN

"use strict";
myFunction();

function myFunction() {
    y = 3.14; // Err: y is not declared
}
x = 3.14; // This will not cause an error. 
myFunction();

function myFunction() {
   "use strict";
    y = 3.14; // This will cause an error
    return this; // this === undefined
}

Event Loop

An Intro to concurrency in JavaScript

More on MDN

  • Why?
  • Stack
  • Heap
  • Queue
  • The Loop

Event Loop

Call stack

More on MDN

function multiply(x, y) {
  return x * y;
}

function printSquare(x) {
  var s = multiply(x, x);
  console.log(s);
}

printSquare(5);

Event Loop

Event Queue

More on MDN

Event Loop

Event Queue

More on MDN

Event Loop

More on MDN

function init() {
  console.log('this is the start');

  setTimeout(function cb1() {
    console.log('this is a msg from call back 1');
  }, 2000);

  console.log('this is just a message');

  setTimeout(function cb2() {
    console.log('this is a msg from call back 2');
  }, 1000);

  console.log('this is the end');
}

init();

Event Loop

Zero Delays

function init() {
  console.log('this is the start');

  setTimeout(function cb1() {
    console.log('this is a msg from call back 1');
  });

  console.log('this is just a message');

  setTimeout(function cb2() {
    console.log('this is a msg from call back 2');
  }, 0);

  console.log('this is the end');
};

init();

Closure

A closure is when a function is able to remember and access the variables of the outer (enclosing) function.

function makeCounter() {
  var count = 0;

  return function counter() {
    return ++count
  }
}

var counter = makeCounter()

counter()  //-> 1
counter()  //-> 2
counter()  //-> 3

Execution Context

Read More

Execution Context

Red Pill or Blue Pill?

You take the blue pill—the story ends, you wake up in your bed and believe whatever you want to believe. You take the red pill—you stay in Wonderland, and I show you how deep the rabbit hole goes. Remember: all I'm offering is the truth.

Execution Context

The abstract concept of the environment in which the current code is being evaluated in.

Execution Context

foo(0)

function foo(i) {
  if (i === 3) {
      return;
  }
  else {
    foo(++i);
  }
}

The Execution Context Stack (Call Stack)

Execution Context

Execution Context Components:

  • LexicalEnvironment
  • VariableEnvironment
    • Both somehow holds identifiers, var declarations, function declarations, arguments...
  • ThisBinding
    • The value of this in the associated execution context.

Execution Context

Every execution context has two phases:

  • Creation/Pre-execution Phase
    • LexicalEnvironment (scope)
      • arguments, variable (w/ undefined initial value) declarations, function declarations
      • A pointer to the outer LexicalEnvironment
    • this binding
  • Execution Phase
    • Assignments, etc.

Execution Context

Creation Phase

foo(22);
var bar = 5;

function foo(i) {
  var a = 'hello'; var b = function B() {}; function C() {}
}
GlobalExecutionContext = {
  ThisBinding: <Global Object>,

  LexicalEnvironment: {
    EnvironmentRecord: {
      Type: "Object",
      bar: undefined,
      foo: <Function foo>
    },
    outer: null
  }
}
GlobalExecutionContext = {
  ThisBinding: <Global Object>,

  LexicalEnvironment: {
    EnvironmentRecord: {
      Type: "Object",
      bar: 5,
      foo: <Function foo>
    },
    outer: null
  }
}

Execution Phase

Execution Context

foo(22);
var bar = 5;

function foo(i) {
  var a = 'hello'; var b = function B() {}; function C() {}
}
fooExecutionContext = {
  ThisBinding: <Global Object>,

  LexicalEnvironment: {
    EnvironmentRecord: {
      Type: "Declarative",
      arguments: {
        0: 22,
        length: 1
      },
      i: 22,
      C: <Function C>,
      a: "hello",
      b: <Function B>
    },
    outer: <GlobalEnvironment>
  }
}
fooExecutionContext = {
  ThisBinding: <Global Object>,

  LexicalEnvironment: {
    EnvironmentRecord: {
      Type: "Declarative",
      arguments: {
        0: 22,
        length: 1
      },
      i: 22,
      C: <Function C>,
      a: undefined,
      b: undefined
    },
    outer: <GlobalEnvironment>
  }
}

Creation Phase

Execution Phase

Execution Context

Scope Chain

var x = 10;

foo()  //-> ?

function foo() {
  var y = 20; // free variable
  function bar() { var z = 15; /* free variable */ return x + y + z; }
  return bar();
}

Execution Context

Read More

IIFE

Immediately Invoked Function Expression

Read More Here & Here

(function(){
  var superSecret = 195;
  // more statements
})();

console.log(superSecret);
// Uncaught ReferenceError: superSecret is not defined
  • To run the declared function immediately
  • New local scope for variables
  • Module Pattern

IIFE

Read More Here

var MyModule = (function () {
  var privateMethod = function () {};
  
  return {
    publicMethodOne: function () {
      // I can call `privateMethod()` you know...
    },
    publicMethodTwo: function () {
      // statements
    },
    publicMethodThree: function () {
      // statements
    }
  };
})();

MyModule.publicMethodOne() // works
MyModule.privateMethod()   // ERR: undefined is not a function

Module Pattern

Inheritance

More on MDN

Topics

Inheritance

More on MDN

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

var john = new Person('John');
john; //-> {name: 'John', __proto__: Object }

var jane = new Person('Jane');
jane; //-> {name: 'Jane', __proto__: Object }

Constructors

Calling a function with new keyword makes it an object constructor

Inheritance

More on MDN

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

var john = new Person('John');
//-> {name: 'John', __proto__: Object }

john instanceof Person //-> true
  • A brand new object obj{} is created.
  • this refers to the created object obj{}.
  • obj.__proto__ is pointed to the Constructor.prototype object.
  • obj{} is returned implicitly if the Constructor does not return anything explicitly.

new Constructor();

Inheritance

More on MDN

function Person (name) {
  // DO NOT ADD METHODS ON 'this' IN CONSTRUCTORS
  this.name = name;
}

// Methods on Person.prototype object
// will accessible by all created objects.
// Notice the value of 'this'
Person.prototype.sayName = function() {
  return this.name
}

var john = new Person('John');
var jane = new Person('Jane');

john.sayName() //-> John
jane.sayName() //-> Jane

Proto Chain (intro)

Inheritance

// Vehicle - superclass
function Vehicle(name) {
  this.name = name;
}
// superclass method
Vehicle.prototype.start = function() {
  return "engine of " + this.name + " starting...";
};
// Car - subclass
function Car(name) {
  Vehicle.call(this, name); // call super constructor.
}
// subclass extends superclass
Car.prototype = Object.create(Vehicle.prototype);
// subclass method
Car.prototype.run = function() {
  console.log("Hello "+ this.start());
};
// instances of subclass
var c1 = new Car("Fiesta");
var c2 = new Car("Baleno");
// accessing the subclass method which internally
// access superclass method
c1.run();   // "Hello engine of Fiesta starting..."
c2.run();   // "Hello engine of Baleno starting..."

More on MDN

Inheritance

Inheritance

Inheritance vs Composition

The Gorilla/banana problem

What you wanted was a banana, but what you got was a gorilla holding the banana, and the entire jungle

Read More

Inheritance

Read More

JavaScript 102

By Behnam Hatami

JavaScript 102

JavaScript 102 / Web Programming Course @ SUT, Fall 2018

  • 1,825