Search code examples
javascriptclosuresprototypechaining

inherit javascript function prototype outside it closure


I am using JavaScript prototype chaining technique to chain functions as shown below:

var foo = (function () {
    function fn(arg) {
        if (!(this instanceof fn)) {
            return new fn(arg);
        }
        this.arg = arg;
        return this;
    }
    var func = function (element) {
        return fn(element);
    };
    fn.prototype = {
        bar: function () {
            return this;
        }
    }
    func.functions = fn;
    return func;
}());

I would like to know how to access fn.prototype so I can add more functionality to the foo prototype outside its closure.

If I just simply do as follows, it won't work:

foo.prototype.baz = function () {
     alert(this.arg);
}
foo("hello").baz();

However if fn assigned to the foo (func.functions = fn;) as it shown in the foo private closure I can do as follow and it will works:

foo.functions.prototype.baz = function () {
     alert(this.arg);
}
foo("hello").baz();

Is there any other way to achieve this?


Solution

  • I think you are un-necessarily overcomplicating this. You can chain by simply doing this:

    const foobar = function(){return this} // Initialize a new Object
    const foo = text => {
        const me = new foobar()
        me.text = text
        me.bar = a => (alert(me.text+": "+a), me)
        return me
    }
    
    foo('A').bar('Test').bar('Test chained')
    
    // Update the foobar class with baz
    foobar.prototype.baz = function() {alert('BAZ worked!');return this}
    
    foo('B').bar('1').baz().bar('2')

    Note: Click Run code snippet to see the output

    That's it!

    Edit:

    You can also do this with ES6 classes like:

    class foobar {
      constructor(text) {
        this.text = text;
      }
      bar(a) {alert(this.text+": "+a);return this}
    }
    
    const foo = text => new foobar(text)
    
    foo('A').bar('Test').bar('Test chained')
    
    // Update the foobar class with baz
    foobar.prototype.baz = function() {alert('BAZ worked!');return this}
    
    foo('B').bar('1').baz().bar('2')