Javascript `this` in objects-in-objects?

2019-03-31 21:21发布

问题:

Sorry for fuzzy post title, I can't formulate the correct name in English for this post.

For example I have such an object:

var APP = {
    a : 1,
    b : function(){
        return this.a;
    }
}

In such way, if I call console.log ( APP.b() ) than this will be referring to APP and result will be 1.

But how to connect to APP from sub-object? Example:

var APP = {
    a : 1,
    b : function(){
        return this.a;
    },
    c : {
        c1: function(){
             return APP.a;
        }
    }
}

console.log ( APP.c.c1() ) // 1

This example works, but it's bad idea to point directly to APP. For example:

APP2 = APP;
APP = null;
console.log ( APP2.b() );  // 1
console.log ( APP2.c.c1() ); // APP is undefined

UPD:

I've got half-decision: if I declare property c like a method:

c : function(){
    var self = this;
    return {
        c1: function(){
            return self.b();
        },
        c2: function(){}
    }
}

It will work, but I should call a method but not property (too much brackets) :

console.log( APP2.c().c1() ) instead of console.log( APP2.c.c1() )

回答1:

You can create a factory method:

var APP = (function(){
   var self;
   return self = {
      a : 1,
      b : function(){
          return this.a; // could be self, only differs in non-context use
      },
      c : {
          c1: function(){
               return self.a;
          }
      }
   };
})();

APP2 = APP;
APP = null;
APP2.b();  // 1
APP2.c.c1(); // 1


回答2:

Two other ways of writing it:

function App() {
    var that = this;
    this.a = 1;
    this.b = function() {
        return this.a();
    };
    this.c = {
        c1: function() {
            return that.a;
        }
    }
}

function App2() {
    var app = {
        a : 1,
        b : function(){
            return this.a;
        },
        c : {
            c1: function(){
                alert(app.a);
            }
        }
    };
    return app;
}


回答3:

you can use more javascriptous way to do that:

var App = function() {
    var that = this;
    this.a = 1;
    this.b = function(){
        return this.a;
    };
    this.c = {
        c1: function(){
             return that.a;
        }
    }
}

var app1 = new App();

...