Frontend Development 10 min read

Design Patterns in Front-End JavaScript Development

This article explains how to apply common design patterns such as Singleton and Observer in front‑end JavaScript, demonstrating practical extensions using Function.prototype, discussing the Open‑Closed Principle, and providing code examples for flexible, maintainable code without invasive modifications.

Hujiang Technology
Hujiang Technology
Hujiang Technology
Design Patterns in Front-End JavaScript Development

In back‑end languages design patterns are widely used (e.g., factory, decorator, singleton), but front‑end code often hides them or avoids them. The article starts with a practical requirement: extend the page.init function with additional behavior without breaking existing logic.

let page = {
  init: () => {
    // many business codes
  },
  ...
};

A straightforward approach adds new code directly inside page.init , which is invasive and fragile, especially when dealing with minified or third‑party code. To solve this, the author introduces a prototype‑based extension method that appends a function after the original one.

Function.prototype.fnAfter = function (fn) {
  var _self = this;
  return function () {
    _self.apply(this, arguments);
    fn.apply(this, arguments);
  };
};

page.init = (page.init || function () {}).fnAfter(function () {
  console.log('我们要追加的功能成功啦~');
});

page.init();

To make the extension chainable like jQuery, the method is refined to return the original result, enabling multiple successive fnAfter calls.

Function.prototype.fnAfter = function (fn) {
  var _self = this;
  return function () {
    var fnOrigin = _self.apply(this, arguments);
    fn.apply(this, arguments);
    return fnOrigin;
  };
};

The article then connects this technique to the Open‑Closed Principle (OCP): software entities should be open for extension but closed for modification. Several classic front‑end design patterns are presented.

Singleton Pattern

var fn = function () { this.instance = null; };
fn.getInstance = function () {
  if (!this.instance) {
    this.instance = new fn();
  }
  return this.instance;
};

var fnA = fn.getInstance();
var fnB = fn.getInstance();
console.log(fnA === fnB); // true

A lazy singleton example shows how to create a modal dialog that is instantiated only when needed, avoiding unnecessary DOM elements.

var createModal = (function () {
  var modal = null;
  return function () {
    if (!modal) {
      modal = document.createElement('div');
      modal.style.display = 'none';
      document.getElementById('container').append(modal);
    }
    return modal;
  };
})();

document.getElementById('showModal').click(function () {
  var modal = createModal();
  modal.style.display = 'block';
});

Observer (Publish‑Subscribe) Pattern

var observal = {
  eventObj: {},
  listen: function (key, fn) {
    this.eventObj[key] = this.eventObj[key] || [];
    this.eventObj[key].push(fn);
  },
  trigger: function (key) {
    var list = this.eventObj[key];
    if (!list) return;
    for (var i = 0; i < list.length; i++) {
      list[i].apply(this, arguments);
    }
  }
};

observal.listen('command1', function () { console.log('黑夜给了我夜色的眼睛~'); });
observal.listen('command1', function () { console.log('我却用它寻找光明~'); });
observal.listen('command2', function () { console.log('一花一世界~'); });
observal.listen('command2', function () { console.log('一码一人生~'); });

observal.trigger('command1');
observal.trigger('command2');

Using this pattern decouples publishers from subscribers, improving flexibility and robustness.

The article warns against premature optimization, suggesting that patterns should be introduced when the codebase shows signs of rigidity or when specific scenarios demand them (e.g., using Redux for complex state sharing). It concludes with a light‑hearted joke and references for further reading.

design patternsfrontendJavaScriptsingletonObserveropen-closed principle
Hujiang Technology
Written by

Hujiang Technology

We focus on the real-world challenges developers face, delivering authentic, practical content and a direct platform for technical networking among developers.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.