Categories
Object-Oriented JavaScript

Object-Oriented JavaScript — Singletons and Decorators

JavaScript is partly an object-oriented language.

To learn JavaScript, we got to learn the object-oriented parts of JavaScript.

In this article, we’ll look at some basic design patterns.

Class-Like Singleton

We can create a singleton object by storing the class instance in a global object.

For instance, we can write:

function Foo() {
  if (typeof globalFoo === "undefined") {
    globalFoo = this;
  }
  return globalFoo;
}

then we can create a Foo instance by writing:

const a = new Foo();
const b = new Foo();
console.log(a === b);

And the console log should log true since we store the existing instance in a global variable.

Then we returned it if it’s not undefined .

Singleton Stored in the Property of the Constructor

We know we shouldn’t use global variables, so we can store the singleton instance as a property of the constructor instead.

Functions can have properties since they are objects.

So we can write:

function Foo() {
  if (typeof Foo.instance === "undefined") {
    Foo.instance = this;
  }
  return Foo.instance;
}

The only change is that we store the property in the instance instead of in a global variable.

We can also store it in a private property if we put it in a function.

So we can write:

const Foo = (() => {
  let instance;
  return function() {
    if (typeof instance === "undefined") {
      instance = this;
    }
    return instance;
  }
})();

and do the same thing.

This way, we can’t accidentally change the instance to something else.

Factory Pattern

The factory pattern is creational design pattern.

It deals with creating objects.

The factory is a function that can help us create similar types of objects with one function.

For instance, we can create a function by writing:

const createElement = (type, url) => {
  if (type === 'Image') {
    return new Image(url);
  }
  if (type === 'Link') {
    return new Link(url);
  }
  if (type === 'Text') {
    return new Text(url);
  }
}

We return the constructor instance based on the type value.

And we also take the url that’s used with the constructors.

Decorator Pattern

The decorator pattern is a structural pattern.

We can use this pattern to extend the functionality of objects.

With this pattern, we can extend an object’s functionality by picking the decorators that we want to apply to the object.

For instance, we can write:

function Person(name) {
  this.name = name;
  this.say = function() {
    console.log(this.name);
  };
}

function DecoratedPerson(person, street, city) {
  this.person = person;
  this.person = person.name;
  this.street = street;
  this.city = city;
  this.say = function() {
    console.log(this.name, this.street, this.city);
  };
}

We have 2 constructors the Person and DecoratedPerson classes.

Person is the class that we use as the base for the DecoratedPerson class.

The DecoratedPerson class adds extra properties on top of the Person class.

This way, we keep the interface of DecoratedPerson the same as the Person constructor for the ones that come from Person .

But we add more properties exclusive to the DecoratedPerson class.

Conclusion

We can create singleton objects with a class like syntax.

The decorator pattern lets us extend the functionality of constructors.

Categories
Object-Oriented JavaScript

Object-Oriented JavaScript — Private Entities and Chaining

JavaScript is partly an object-oriented language.

To learn JavaScript, we got to learn the object-oriented parts of JavaScript.

In this article, we’ll look at some basic coding and design patterns.

Privileged Methods

Privilege methods is a term coined by Douglas Crockford.

These are public methods that can access private methods and properties.

They act as a bridge to make some private functionality available in a controlled manner.

For instance, we can write:

let APP = {};
APP.dom = (() => {
  const setStyle = function(el, prop, value) {
    console.log('setStyle');
  };

  const getStyle = function(el, prop) {
    console.log('getStyle');
  };

  return {
    setStyle,
    getStyle,
    //...
  };
}());

We have the setStyle and getStyle functions that are defined in the IIFE.

We expose them by return the object and then assigning it to a property that’s available outside the function.

These functions can have private variables inside them so that we can do whatever we want without exposing everything.

Immediate Functions

Immediate functions let us keep global namespace clean by wrapping our code in an anonymous function and run them immediately.

For instance, we can write:

(function() {
  // ...
}());

to create a function and call it immediately.

This way, we can keep private variables and methods inside it.

For example, we can write:

let APP = {};
APP.methods = (() => {
  function _private() {
    // ...
  }
  return {
    foo() {
      console.log('...');
      _private();
    },
    bar() {
      console.log('...');
    }
  };
}());

We have the IIFE, which returns an object with the foo method that calls the private _private function.

Modules

ES5 doesn’t have modules, so we may have to use modules for scripts if we’re writing scripts for the browser.

For instance, we can create a module by writing:

let APP = {
  module: {}
};
APP.module.foo = (() => {
  const another = APP.module.another;
  let foo, bar;

  function hidden() {}
  //...

  return {
    hi() {
      return "hello";
    }
  };
}());

We created a foo module which references an another module.

In the module, we defined some variables and the hidden function.

And we return a public hi method in an object.

Then we can hi by writing:

APP.module.foo.hi()

Chaining

Chaining is a pattern that lets us call multiple methods in one line.

The methods are linked to a chain.

For instance, we can write:

class Foo {
  foo() {
    this.foo = 'foo';
    return this;
  }

  bar() {
    this.bar = 'bar';
    return this;
  }

  baz() {
    this.baz = 'baz';
    return this;
  }
}

We have multiple methods that return this , which is the Foo instance.

This way, we can call the methods in a chain.

So we can write:

new Foo().foo().bar().baz();

to call the chain of methods.

Conclusion

We can have private variables, objects, and functions that are inside a function.

Also, we can create our own modules with our own objects.

And we can make them chainable by returning this in a method.

Categories
Object-Oriented JavaScript

Object-Oriented JavaScript — Observers and Tests

JavaScript is partly an object-oriented language.

To learn JavaScript, we got to learn the object-oriented parts of JavaScript.

In this article, we’ll look at some basic design patterns and tests.

Observer Pattern

The observer pattern is where we observe the changes from the one source by subscribing to an object and publish the changes to the observers that subscribed when there’re changes.

We can create an object that takes observers and publish changes to them by writing:

const observer = {
  subscribers: [],
  addSubscriber(callback) {
    if (typeof callback === "function") {
      this.subscribers.push(callback);
    }
  },

  removeSubscriber(callback) {
    const index = this.subscribers.findIndex(s => s === callback);
    this.subscribes.splice(index, 1);
  },

  publish(obj) {
    for (const sub of this.subscribers) {
      if (typeof sub === 'function') {
        sub(obj);
      }
    }
  },
};

We create an observer object that takes callbacks.

callback is a function that we add to the subscribers array.

Also, we have the removeSubscriber array to remove a callback.

publish takes an object with something to publish and callbacks the callbacks in the this.subscribers array to publish the changes.

Then we can use it by writing:

const callback = (e) => console.log(e);
const callback2 = (e) => console.log(2, e);
observer.addSubscriber(callback);
observer.addSubscriber(callback2);
observer.publish('foo')

We created 2 callbacks and add them to the subscribers array with the addSubscriber method.

Then we call publish to call the callbacks, which log the changes.

We should see:

foo
2 "foo"

logged in the console log.

The observer pattern is good since there’s not much coupling between the callbacks and the observer object.

We just call the callback when there’s some information to send to them.

The callbacks know nothing about the observer .

Testing

Testing is an important part of writing JavaScript apps.

We can make our lives easier by writing tests that run automatically.

Not having enough tests is a bad idea.

With tests, we make sure that the existing code behaves as per our specifications.

And any new code changes didn’t break existing behavior defined by our spec.

With tests, we don’t have to test everything ourselves by hand.

Also, we won’t have to check everything ourselves again when we refactor.

If our changes make the tests fail, then we know there’s something wrong.

Unit Testing

Unit testing is what we have the most of.

They’re short and they run fast.

They test the output given some input.

And they should be self-explanatory, maintainable and readable.

They should also work the same way in any order.

Test-Driven Development

Test-driven development is used a lot recently,

The methodology workflow starts by writing some tests that fail.

And then we write code to make the tests pass.

Then we run the tests again to see if they pass.

And then we refactor our code and make sure our tests still pass.

Behavior Driven Development

Behavior-driven development is a methodology where we create tests to test how our code behaves.

We test with some inputs and check th outputs.

Conclusion

We can create unit tests to test our code.

Also, the observer pattern lets us create loosely coupled code that communicates from the observer to another object.

Categories
Object-Oriented JavaScript

Object-Oriented JavaScript — Lazy Definition and Private Variables

JavaScript is partly an object-oriented language.

To learn JavaScript, we got to learn the object-oriented parts of JavaScript.

In this article, we’ll look at some basic coding and design patterns.

Lazy Definition

The lazy definition pattern is where we assign the function to a property when we run it.

For instance, we can write:

const APP = {};
APP.click = {
  addListener(el, type, fn) {
    if (el.addEventListener) {
      APP.click.addListener = function(el, type, fn) {
        el.addEventListener(type, fn, false);
      };
    } else if (el.attachEvent) {
      APP.click.addListener = function(el, type, fn) {
        el.attachEvent(`on${type}`, fn);
      };
    } else {
      APP.click.addListener = function(el, type, fn) {
        el[`on${type}`] = fn;
      };
    }
    APP.click.addListener(el, type, fn);
  }
};

We have the addListener method which runs when we run the APP.click.addListener method.

We can set the function according to which one is available.

Configuration Object

We can create a configuration object to let us get configuration from there.

Objects are better than parameters because their order doesn’t matter.

We can also easily skip parameters that we don’t want to add.

It’s easy to add an optional configuration.

The code is more readable because the config’s object’s properties are in the code.

For example, instead of writing:

APP.dom.CustomDiv = function(text, color) {
  const div = document.createElement('div');
  div.color = color|| 'green';
  div.textContent = text;
  return div;
};

We write:

APP.dom.CustomDiv = function({
  text,
  color = 'green'
}) {
  const div = document.createElement('div');
  div.color = color;
  div.textContent = text;
  return div;
};

We destructured the object properties so that we can use the variables.

It’s shorter and cleaner.

And the order doesn’t of the properties don’t matter.

We just pass in an object as the parameter to use it:

new APP.dom.CustomDiv({ text: 'click me', color: 'blue' })

It’s easy to switch the parameters’ order if they’re in an object.

All the properties should be independent and optional.

Private Properties and Methods

We can keep properties and methods with JavaScript by keeping them in an object.

For instance, we can write:

APP.dom.CustomDiv = function({
  text,
  type = 'sumbit'
}) {
  const styles = {
    font: 'arial',
    border: '1px solid black',
    color: 'black',
    background: 'grey'
  };

  const div = document.createElement('div');
  div.styles = {
    ...div.styles,
    ...styles
  };
  div.type = type;
  div.textContent = text;
  return div;
};

We have the styles object that has the styles we want to apply to the div.

Since it’s inside the function, we can’t change it from the outside.

We can also add a method to set the styles inside the method:

APP.dom.CustomDiv = function({
  text,
  type = 'sumbit'
}) {
  const styles = {
    font: 'arial',
    border: '1px solid black',
    color: 'black',
    background: 'grey'
  };

  const div = document.createElement('div');
  const setStyles = (el) => {
    el.styles = {
      ...el.styles,
      ...styles
    };
  }

  div.type = type;
  div.textContent = text;
  setStyles(div);
  return div;
};

We have the setStyles private function that can only be called inside the CustomDiv constructor.

Conclusion

We can assign fu7nctions to a property when we call them.

Also, we can keep values private by putting them inside the function.

Categories
Object-Oriented JavaScript

Object-Oriented JavaScript — JSON vs XML and Singletons

JavaScript is partly an object-oriented language.

To learn JavaScript, we got to learn the object-oriented parts of JavaScript.

In this article, we’ll look at some basic coding and design patterns.

Use JSON

JSON is a popular lightweight format for exchanging data.

It’s better than XML since we can convert between JSON string and JavaScript objects easily.

An example of a JSON string includes:

{
  'a': 1,
  'b': 2,
  'c': 3
}

XML code is like:

<?xml version="1.0" encoding="UTF-8"?>
<response>
   <name>james</name>
   <books>
      <book>foo</book>
      <book>bar</book>
      <book>baz</book>
   </books>
</response>

It’s hard to convert XML code into JSON with JavaScript.

We have to install a library to do it.

But we can convert between a JSON string and an object literal with JSON.parse and JSON.stringify .

Also, XML code is longer with all the opening and closing tags.

JSON parsing and stringifying methods are also available in standard libraries of other languages like PHP.

Higher-Order Functions

Functional programming is confined to a limited set of languages.

JavaScript is one of the programming languages that have some functional programming features.

Higher-order functions are one of the basic features of functional programming.

A higher-order function is a function that takes one or more functions as arguments or returns a function as a result.

JavaScript functions can take functions as arguments and return functions.

They’re treated like other objects.

For instance, the array instance’s map method takes a function to let us map array entries to something else.

For instance, we can write:

[1, 2, 3, 4, 5].map(a => {
  return a ** 2;
})

We square each array entry and return an array with the squared entries.

The function we passed in is called on each entry and the returned result is added to the returned array.

We can write higher-order functions easily with arrow functions.

For instance, instead of writing:

function add(x) {
  return function(y) {
    return y + x;
  };
}
const add5 = add(5);

We write:

const add = x => y => y + x;
const add5 = add(5);

It’s much shorter and cleaner.

In both add functions, we take the parameter and return a function that takes a parameter y , add that with x and returns it.

Design Patterns

Design patterns are commonly-used language-agnostic ways for organizing our code.

The Gang of Four book is the most popular book with design patterns.

There’re several kinds of design patterns.

Creational patterns deal with how objects are created.

Structural patterns deal with how different objects are composed to provide new functionality.

Behavioral patterns provide us with ways for objects to communicate with each other.

Singleton Pattern

Singleton pattern is a creational design pattern.

In the pattern, we create only one object from any kind of class.

In JavaScript, we can do this simply with an object literal.

For instance, we can write:

const single = {};

to create an object literal.

Conclusion

We should use JSON for communication since it’s easier to serialize and parse.

Also, higher-order functions are used everywhere in JavaScript.

And we can create singleton objects with object literals.