Private fields

In object oriented programming, a private field is a field that can only be altered by methods of a its class. although JavaScript does not have a working private keyword, to achieve this, we can hide a variable inside a closure preventing its use from the outside.

function counter(start) {
  return {
    get next() {
      return start++;
    }
  };
}

var id = counter(0);

console.log(id.next);
console.log(id.next);
console.log(id.next);

Monkey patching

Monkey patching is when you replace a function with a function that runs some code before and or after calling the original function. The following example is a function that is able to patch other functions to log each call.

function log(f) {
  return function () {
    var args = [].slice.call(arguments);
    var result = f.apply(null, args);
    console.log(f.name + '(' + args.join(', ') + ') = ' + result);
    return result;
  }
}

function fibonacci(n) {
  if (n == 0) return 0;
  if (n == 1) return 1;
  return fibonacci(n - 1) + fibonacci(n - 2);
}

fibonacci = log(fibonacci);

fibonacci(5);

Calling super

There wasn't a super keyword in JavaScript until ES6, but we could still call the method of the parent class using monkey patching or using the prototype of the parent class.

ES5

function Counter(start) {
  this.start = start;
}

Counter.prototype.count = function () {
  return this.start++;
}

function DoubleCounter(start) {
  // Calling the constructor of the super class
  Counter.call(this, start);
}

DoubleCounter.prototype = Object.create(Counter.prototype);
DoubleCounter.prototype.constructor = DoubleCounter;

DoubleCounter.prototype.count = function () {
  // Calling method of the super class
  return 2 * Counter.prototype.count.call(this);
}

var doubleCounter = new DoubleCounter(1);
console.log(doubleCounter.count());
console.log(doubleCounter.count());

ES6

class Counter {

  constructor(start) {
    this.start = start;
  }

  count() {
    return this.start++;
  }
}

class DoubleCounter extends Counter {

  constructor(start) {
    super(start);
  }

  count() {
    return 2 * super.count();
  }
}

var doubleCounter = new DoubleCounter(1);
console.log(doubleCounter.count());
console.log(doubleCounter.count());

Alternative

function counter(start) {

  function count() {
    return start++;
  }

  return {count: count};
}

function doubleCounter(start) {

  var simple = counter(start);

  function count() {
    return 2 * simple.count();
  }

  return {count: count};
}

var doubleCounter = doubleCounter(1);
console.log(doubleCounter.count());
console.log(doubleCounter.count());

Inheritance

Inheritance allows us to share code between classes. If two classes have many common features and we can say that one class is a type of another class, then we can use inheritance to make the more specific class use code from the more generic class.

As an example think about the classes bird and duck. Duck is a type of bird and we expect that a duck can do everything that a bird can do like flying. So we make the class duck inherit the class bird. By doing that we need to write the method fly only once.

Composition is an alternative to inheritance. Instead of sharing fields with the super class we instead add an instance of the super class as a new field. This allows us to not worry about having fields of the super and sub classes with the same name.

ES5

function Bird() {}

Bird.prototype.fly = function () {
  console.log("Zoom!");
};

function Duck() {}

Duck.prototype = Object.create(Bird.prototype);
Duck.prototype.construtcor = Duck;

Duck.prototype.swim = function () {
  console.log("Splash!");
};

var donald = new Duck();
donald.swim();
donald.fly();

ES6

class Bird {
  fly() {
    console.log("Zoom!");
  }
}

class Duck extends Bird {
  swim() {
    console.log("Splash!");
  }
}

var donald = new Duck();
donald.swim();
donald.fly();

Alternative

function bird() {

  function fly() {
    console.log("Zoom!");
  }

  return {fly: fly};
}

function duck() {

  function swim() {
    console.log("Splash!");
  }

  return {swim: swim, bird: bird()};
}

var donald = duck({});
donald.swim();
donald.bird.fly();

Mixins

Mixins are multiple inheritances, it happens when a class is a type of two other classes, and those two other classes are not a type of each other.

As an example think of the Pooh bear. It is a talking bear. Since not all bears talk, and not all taking things are bears, we can't just use simple inheritance because Pooh needs to inherit from both classes.

In my personal approach I used composition instead of inheritance. Polymorphism in JavaScript makes little sense, since variables are not locked to a type. And composition allows me to avoid name clashes that happens when the sub class has fields named after the super classes.

ES5

function union(a, b) {
  var c = {};

  for (var i in a) c[i] = a[i];
  for (var i in b) c[i] = b[i];

  return c;
}

function Bear() {}

Bear.prototype.eat = function (food) {
  console.log(food + ", yummy!");
};

function Talking() {}

Talking.prototype.say = function (message) {
  console.log(message);
};

function TalkingBear() {}

TalkingBear.prototype = Object.create(union(Bear.prototype, Talking.prototype));
TalkingBear.prototype.constructor = TalkingBear;

var pooh = new TalkingBear();
pooh.eat("Honey");
pooh.say("Hello");

Alternative

function bear() {
  function eat(food) {
    console.log(food + ", yummy!");
  }

  return {eat: eat};
}

function talking() {

  function say(message) {
    console.log(message);
  }

  return {say: say};
}

function TalkingBear() {
  return {bear: bear(), talking: talking()};
}

var pooh = TalkingBear();
pooh.bear.eat("Honey");
pooh.talking.say("Hello");

Callbacks with data

Since JavaScript is single threaded most API is asynchronous. In this case, the result of the API is not ready in the line following the call, it is only ready in the callback function you pass to the API.

A common problem with callbacks arises when you try to access data inside the callback or pass some specific data for each callback.

Passing data to each callback problem

var array = [1, 2, 3, 4];

for (var i = 0; i < array.length; ++i) {
  setTimeout(function () {
    console.log(array[i]);
  });
}

Here, only undefined is printed, because all functions have a reference to the variable i with the value after the end of the loop. Callbacks rarely run immediately, and in this case, all callbacks are run after the loop.

forEach

var array = [1, 2, 3, 4];

array.forEach(function (i) {
  setTimeout(function () {
    console.log(i);
  });
});

Here, for each element of the array a new function is called with the value of the array as argument. The variable is always called i, but each i is unique since it holds a different value.

Closure

var array = [1, 2, 3, 4];

for (var i = 0; i < array.length; ++i) {
  setTimeout(function (i) {
    return function () {
      console.log(array[i]);
    }
  }(i));
}

Another way to solve this problem is to use a function that takes the argument that we want to pass to our callback and returns a newly created callback. The callback can access the variable of its parent function because it is in its closure.

Partial application

var array = [1, 2, 3, 4];

for (var i = 0; i < array.length; ++i) {
  setTimeout(function (i) {
    console.log(array[i]);
  }.bind(null, i));
}

Partial application is the process of fixing the value of some argument to a function reducing its arity (number of arguments it takes). In this example the argument i is fixed by bind to the value of each iteration.

Block scoped variables

var array = [1, 2, 3, 4];

for (let i = 0; i < array.length; ++i) {
  setTimeout(function () {
    console.log(array[i]);
  });
}

The keyword var in JavaScript defines variables in lexical scope, they are available everywhere in the function. The keywords let and const in the other hand define variables with block scope, so they are only available inside the block.

this inside callbacks

function Bear(color) {
  this.color = color;
}

Bear.prototype.eat = function (food) {
  var self = this; // warning: easy to forget.
  setTimeout(function () {
    // this.color won't have the string here without bind.
    console.log("A " + self.color + " bear ate " + food + ".");
  }, 3000);

  return this;
};

(new Bear("gray")).eat("honey");

this is a reference to an instance of Bear only if the function is called from the object, but the callback is called in a different context usually not as a method, so the value of this is the global object.

Using lambdas to preserve the value of this

class Bear {

  constructor(color) {
    this.color = color;
  }

  eat(food) {
    setTimeout(() => {
      console.log("A " + this.color + " bear ate " + food + ".");
    }, 3000);
  }
}

(new Bear("gray")).eat("honey");

Different than functions, lambdas use the value of this of its parent. In this case the parent of our callback is a regular method with the proper value of this set.

Avoid using this

function bear(color) {

  function eat(food) {
    setTimeout(function () {
      // color is available here via closure
      console.log("A " + color + " bear ate " + food + ".");
    }, 3000);
  }

  return {eat: eat};
}

bear('gray').eat('honey');

It is not always necessary to use this to access the state of your objects. Another way to create objects is to keep the state in the closure, this way the keyword this is not necessary and the state of the object becomes private.