Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript - What is the best method when creating chainable functions?

EDIT
Here is an attempt to make my question simpler.

return this.someFunc(); == return { XXX:this.someFunc() };

What do I have to put in for XXX to make this statement true?


I'm trying to create a function that can be chained. Let me write some hypothetical code. (Any syntax errors just ignore, I'm typing this fast and this is just concept code.) Assume that all functions are either defined locally or globally. :)
test = function(){
  this.someFunc = function(){
    this.retest = function(){
      //...code
    }
    //...code
  }
  this.someFunc2 = function(){
    //...code
  }
  return this.someFunc();
}

This function allows me to chain: test().retest();
But what I want to do is return more than one item.

test = function(){
  this.someFunc = function(){
    this.retest = function(){
      //...code
    }
    //...code
  }
  this.someFunc2 = function(){
    //...code
  }
  return { XXX:this.someFunc(), //What do I put for XXX
           next:this };
}

I want to do this to access another function that test() offers: test().next.someFunc2();

So my problem is this:
I still want to be able to chain like this: test().retest();
But I have to do it like this: test().XXX.retest();

In my code, what is the name that I can put instead of XXX to accomplish this? And is this even possible? I have tried 0 and default already. Thanks for the help.

like image 993
Aust Avatar asked Aug 21 '12 22:08

Aust


2 Answers

You can make a chainable functions like this:

var test = function(){

    var self = {};
    console.log('test called')

    function someFunc() {
        console.log('someFunc')
        return self;
    }

    function someOtherFunc() {
        console.log('someOtherFunc')
        return self;
    }   

    self.someFunc = someFunc;
    self.someOtherFunc = someOtherFunc;
    return self;

}

test().someFunc().someOtherFunc();

Hope this helps

like image 124
Sebastian Avatar answered Oct 09 '22 07:10

Sebastian


function test() {
   // when test() is called as a regular function
   // it's `this` will be `undefined` (in strict mode) or will refer to a global object
   // when test() is called with `new` operator
   // it's `this` will be an instance of `test` object
   if(!(this instanceof test)) {
      // create a new object
      return new test();
   }
   else {
      // this is a `new object` creation              
      console.log('new Test created');
   }
}

// declare functions which will be accessible on test object
test.prototype.someFunc = function() {
    console.log('someFunc');
    return this;
};

test.prototype.someFunc2 = function() {
    console.log('someFunc2');
    return this;
};

// declare a `chaining` function - will create a new `test` object
test.prototype.test = function() {
    return new test(); // new instance will be created
};

With this code you are now able to run the following code

test().someFunc().someFunc2().test().someFunc().someFunc().test().test()

The following string will be written at the console

new Test created
someFunc
someFunc2
new Test created
someFunc
someFunc
new Test created
new Test created
like image 34
Olegas Avatar answered Oct 09 '22 06:10

Olegas