0

I've got a JS object that looks like so:

return {
  foo: function() {
    return this.bar();
  },

  bar: function() {
    return 1;
  }
}

Why do I keep getting a TypeError: this.bar is not a function logged in FireBug? What's the proper way to reference the bar() method from foo() in the same object?

Update

So I've posted a fiddle with the whole code here. The return call is actually part of a RequireJS define. Let me know if any further clarification is required.

6
  • can you please provide a fiddle for that? it works in Chrome. Commented Oct 31, 2013 at 7:45
  • 2
    this depends on how you call it. Commented Oct 31, 2013 at 7:46
  • Can you post some more code, i.e. the function where this return is included, and the invocation calls you are using? Commented Oct 31, 2013 at 7:46
  • can you provide more sample code? Commented Oct 31, 2013 at 7:46
  • @Lean: done: jsfiddle.net/4ghuq Commented Oct 31, 2013 at 7:54

1 Answer 1

3

It depends on how it is called; If for instance theObject.foo is passed as callback to another function (e.g. jQuery(x).on("click", theObject.foo)), the this context will probably be lost.

A way to enforce that bar calls foo is to make a closure. Change the function that returns the object as:

function thatReturnsTheOject() {
    var ret = {
        foo: function() {
            return ret.bar(); // <---- Using `ret` not `this`
        },
        bar: function() {
            return 1;
        }
    };
    return ret;
}

Another way, more complex but may result in a more familiar language usage is this:

function thatReturnsTheOject() {
    var ret = {};

    ret.foo = (function() {
        return this.bar(); // <---- Using `this` again
    }).bind(ret);          // <---- but note the `bind()`

    ret.bar = function() {
        return 1;
    };

    return ret;
}
Sign up to request clarification or add additional context in comments.

5 Comments

Do you know of a way to force the reference to bind to the same object (kinda like self in PHP)?
You mean when you use the reference? E.g. do jQuery(x).on("click", theObject.foo), use this in foo() and still reference the correct object?
No, i mean within the object itself. Is there a keyword I put in place of this to mimic the functionality i'm looking for?
No, there is no such thing. You could do something that looks familiar: name the returned object self instead of ret, so you can use return self.bar();. Still this is only a game of words, not a solution as the one you are asking. See the edit using Function.bind(), but I doubt it is really better...
Your answer works great. I'm just being inquisitive. Thanks old chap!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.