0

I have a object a:

var a = {
    b: {
        f1: function(){console.log('in a.b.f1')}
    },
    c: {
        _this: this,
        f2: function(){this._this.b.f1()}
    }
}

then, I found the error TypeError: Cannot call method 'f1' of undefined

How should I call a.b.f1() in a.c.f2?

Dan D.
  • 73,243
  • 15
  • 104
  • 123
Ricter Z
  • 11
  • 3
  • See my post and let me know if you can't understand something – nanobash Mar 01 '14 at 08:55
  • possible duplicate of [Self-references in object literal declarations](http://stackoverflow.com/questions/4616202/self-references-in-object-literal-declarations) - whether it's nested or not does not matter. – Bergi Mar 02 '14 at 15:21

1 Answers1

3

The answer is in the question, use a.b.f1().

By default, this refers to the object which owns the function. If the function is "free", this refers to the global window object. If this is not wrapped inside a function, it refers to window as well.

// "this" is window
function f() { /* "this" is "window" */ }
var o = {};
o.f = function () { /* "this" is "o" */ }
o.child = {};
o.child.f = function () { /* "this" is "o.child" */ }

Knowing this and considering your code, we can say that this does not refer to a since it's not contained in a function owned by a. As a workaround, you could simply replace this with a :

var a = {};
a.b = {
    f1: function () { console.log('in a.b.f1'); }
};
a.c = {
    parent: a,
    f2: function () { this.parent.b.f1(); }
};

Notice that you can "redirect" this to another object using call() or apply() :

o.child.f.call(o); // "this" is now "o" inside of "o.child.f"
  • 1
    [`bind`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind) is also useful for creating functions that will always have `this` bound to a specific object. – Useless Code Mar 01 '14 at 11:08
  • Thank you, but in the console I found that:`a.c Object {parent: undefined, f2: function}` – Ricter Z Mar 02 '14 at 13:12