Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A native way of adding custom JavaScript functions into a method-calls chain

I would like to known if there is a native way of doing this :

Object.prototype.chain = function(f) { return f.call(this) }


function fun1() {
    doSomethingWithObject(this)
    return this
}

function fun2() {
    doSomethingElse(this)
    return this
}

someObject
    .method1('something')
    .method2()
    .chain(checkSomething() ? fun1 : fun2)
    .method3()

But I do not feel like changing the prototype of Object. Is there a way to do this without modifying the prototype of Objects or the other constructors that I use (and am not the developer of)

Edits :

I feel I do not explain very well, so let' add some details :

What I would like to do is to use some APIs I do not define. someObject is defined like the following, with chainable methods :

var someObject = {
    method1: function(val) {
        // do something
        return this
    },
    method2: function() {
        // do something
        return this
    },
    method3: function() {
        // do something
        return this
    }
}

Now imagine I cannot change this code, because this object is from a library, and so I don't want to. Then, imagine that I would like to chain methods and some custom functions (see my first snippet) for many more different objects. The simplest thing to do is to attach a chain method to Object.prototype.

But I think that it could result in conflicts in the future. I am looking for a way to do the same thing without touching the prototype.

like image 953
lud Avatar asked May 28 '15 08:05

lud


1 Answers

I'm surprised there are no answers to this to be honest.

There are many ways to natively introduce chaining. I like to use the revealing module pattern.

So I create a basic model (Go ahead and chuck this in your chrome of firefox console)

var Dog = function(name) {
    var self = this;
    this.name = name;


     var core = {
            getName:function(){
                return self.name;
            }
        }; 

    this.movement = function(){     //this function will be exposed including its returned functions for chaining      
        console.log(self.name + " is getting restless... ");

        var jump = function(){
            console.log(self.name + " jumps around ");
            return this //returns the movement scope
        };
        var run = function(){
            console.log(self.name + " has decided to run");
            return this //returns the movement scope
        };

        return {
            jump:jump,
            run:run           
        };

    }       
    console.log("A Pup has been born, we shall call him... " + name);
    return{
        movement:self.movement    //only .movement is exposed to the outside world
    };
    }

Now create a new dog using var p = new Dog("doggyName");

now, you can chain functions. Try:

p.movement().jump().run().jump().run();

You should get the console logged text that corresponds with each function.

By returning the scope of this after executing your movement function you expose the additional functions that are returned in that scope (see the comments in the code). These can then be chained onto the end of your current function provided they are in the same scope. This allows you to scope specific parts of your code. For example with this dog, all movement is scoped to self.movement, you could have all eating scoped to self.eat and so on

Read up on the revealing module pattern. Though this is not the only way to do it.

like image 106
Jay Avatar answered Sep 23 '22 04:09

Jay