Search code examples
javascriptprototypeextend

Extending existing Object to add additional JavaScript Prototype methods


Let's say I have a function like the one below that creates a very simple micro-library:

var microLib = function(selector) {
    var el;
    var selectorEngine = function(selector)
    {
        var selector_value = selector.slice(1);
        return document.getElementById(selector_value);
    };

    el = selectorEngine(selector);

    Element.prototype.func_1 = function(){
        return 'first';
    };

    Element.prototype.func_2 = function(){
        return 'second';
    };

    return el;
};
window._$ = microLib;

This script will allow me to write code like this:

var elem = _$("#div_with_id");   //some element on my web page
console.log(elem.func_2());      //outputs 'second' in the console 

So now, I'm looking for a way to extend _$ in a supplementary piece of code to add additional Element.prototype methods, which will allow me to write:

console.log(elem.func_3());    //to output 'third' in the console

The reason I need to do this is because this extension needs to take place in another JavaScript file, otherwise I would I have just added another method and be done with it.

How can I do this?


Solution

  • Here's an example of the approach that I am suggesting: http://jsfiddle.net/rbxssmx8/.

    JS:

    var toArray = Function.prototype.call.bind(Array.prototype.slice);
    var qAll = document.querySelectorAll.bind(document);
    
    var _$ = (function() {
        function dom(selector) {
            if(!(this instanceof dom)) {
                return new dom(selector);
            }
    
            this.elements = toArray(qAll(selector));
        }    
    
        dom.prototype.iterate = function(func) {
            this.elements.forEach(func);
            return this;
        };
    
        dom.prototype.addClass = function() {
            var klasses = arguments;
            return this.iterate(function(element) {
                element.classList.add.apply(element.classList, klasses);
            });
        };
    
        dom.extend = function(name, func) {
            this.prototype[name] = func;    
        };
    
        dom.ready = function(func) {
            document.addEventListener("DOMContentLoaded", func);    
        };
    
        return dom;
    })();
    
    _$.extend("removeClass", function() {
        var klasses = arguments;
        return this.iterate(function(element) {
            element.classList.remove.apply(element.classList, klasses);    
        });
    });
    
    _$("div").addClass("gray");
    var $el = _$("div:last-of-type");
    $el.removeClass("gray");