2

I am trying to create an object with multiple methods, but I want some methods to use other methods from the same object. Here is an example:

var myObj = {
    sum: function (a,b) {
        return a + b;
    },
    somethingThatUsesSum: function (a,b) {
        return this.sum(a,b) * 5;
    }
};

This "works" if you call it as follows:

myObj.somethingThatUsesSum(1, 2);

because this is set to myObj. However, if you use apply, it doesn't work unless you explicitly set this to be myObj.

I don't like using this in somethingThatUsesSum, but I'm wondering if there is a better way.

I know I could create a closure with a local function sum that can be used by both functions in myObj, but I wanted to know if there was another way closer to the approach proposed above.

Mark Sherretta
  • 10,160
  • 4
  • 37
  • 42
  • 1
    That's just the way JavaScript works. The fiercely-deprecated `with` statement provides one way to avoid explicitly referencing `this`, but it has other problems. – Pointy Oct 21 '13 at 15:23
  • Thanks Pointy. I thought that was the case, but I wanted to know if I was missing something that could result in a simplified solution. – Mark Sherretta Oct 21 '13 at 15:23
  • What's the scenario where you're using apply? – bfavaretto Oct 21 '13 at 15:26
  • Other code could call this function with apply and then it wouldn't work unless they passed myObj as the first argument to apply. That seems like a code smell to me. – Mark Sherretta Oct 21 '13 at 15:33
  • 1
    Think of `this` as "current object". You can apply your function to another object, as long as it also has a `sum` method. – bfavaretto Oct 21 '13 at 16:15
  • @MarkSherretta: If you're passing a method reference to some code which you don't trust you can use [`bind`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind): `myObj.somethingThatUsesSum.bind(myObj)`. Another way would be to just [reference `myObj` instead of `this`](http://stackoverflow.com/q/10711064/1048572) – Bergi Oct 21 '13 at 16:30

1 Answers1

0

Like Pointy said, that's just the way Javascript works, but in this case you can do this (tested):

var myObj = {
    sum: function (a,b) {
        return a + b;
    },
    somethingThatUsesSum: function (a,b) {
        return myObj.sum(a,b) * 5;
    }
};
myObj.somethingThatUsesSum.apply(0,[3,5])// Or ...UsesSum.call(0,3,5)
// => 40
//0 stands for "I don't care what this is invoked on"
Sophiα2329
  • 1,601
  • 1
  • 13
  • 15