Skip to content

Instantly share code, notes, and snippets.

@taufik-nurrohman
Last active May 12, 2017 17:09
Show Gist options
  • Save taufik-nurrohman/a22df22aa749a750497879ba0597c3a7 to your computer and use it in GitHub Desktop.
Save taufik-nurrohman/a22df22aa749a750497879ba0597c3a7 to your computer and use it in GitHub Desktop.
JavaScript Module Pattern
/*! JavaScript Module Pattern by Taufik Nurrohman <https://github.com/tovic> */
(function(win, doc, NS) {
(function($) {
// module version
$.version = '1.0.0';
// collect all instance(s)
$.__instance__ = {};
// plug to all instance(s)
$.each = function(fn, t) {
return setTimeout(function() {
var ins = $.__instance__, i;
for (i in ins) {
fn(ins[i], i, ins);
}
}, t === 0 ? 0 : (t || 1)), $;
};
})(win[NS] = function(target, config) {
var $ = this;
// return a new instance if `MyModule` was called without the `new` operator
if (!($ instanceof win[NS])) {
return new win[NS](target, config);
}
// access module instance from `this` scope with `this.MyModule`
target[NS] = $;
// store module instance to `MyModule.__instance__`
win[NS].__instance__[target.id || target.name || Object.keys(win[NS].__instance__).length] = $;
// access module target with `$.target`
$.target = target;
// create some method(s) …
$.set = function() {
// ...
return $; // make chainable …
};
$.get = function() {
// ...
return $; // make chainable …
};
$.reset = function() {
// ...
return $; // make chainable …
};
// return the global object
return $;
});
})(window, document, 'MyModule');
@taufik-nurrohman
Copy link
Author

taufik-nurrohman commented Oct 30, 2016

I started to implement this pattern on all of my JavaScript project because this pattern allows me to add additional functionality without having to access the variable of the instance with this:

MyModule.each(function(a, b, c) {

    // add `foo` method to all `MyModule` instances
    a.foo = function() {  };

    // a: refers to the instance object
    // b: refers to the instance key in `MyModule.__instance__`
    // c: refers to `MyModule.__instance__`
    console.log(arguments);

});

Inspired by that CKEDITOR.instances object. By default, the instance scrapper will set a new item in MyModule.__instance__ with a key generated by the target ID or target name or target index in the page.

var module = new MyModule(document.getElementById('foo'));

// chaining …
module.set().get().reset();

// access `MyModule` instance from `this` scope
module.target.addEventListener("click", function() {
    console.log(this.MyModule);
}, false);

// test …
console.log(MyModule.__instance__);
console.log(MyModule.__instance__['foo'].target);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment