3

My issue is I have 2 inner objects in my js class and I'm trying to use the methods from one of those objects in my other object (examples of what I'm trying to do below). I understand why this doesn't work because of a the scope. I'm just wondering if there is a way to get it to work.

var Class1 = {

    self : this,
    Obj1 : {

        Obj1Method : function () {
            alert("Do something");
        },
        Obj1Method2 : function () {
            alert("Do something else");
        },

        InnerObj1 : {
            InnerNestObj1Method : function (val) {
                alert(val + 2);
            }
        }
    },

    Class1Method2 : function () {
        this.Obj1.Obj1Method2();
    },

    Obj2 : {

        Obj2Method : function (val2) {
            self.Obj1.InnerObj1.InnerNestObj1Method(val2);
        },

        Obj2Method2 : function () {
            self.Class1Method2();
        }
    }
};

Class1.Obj1.InnerObj1.InnerNestObj1Method(3); //works
Class1.Class1Method2(); //works
Class1.Obj2.Obj2Method2(); //No bueno
Class1.Obj2.Obj2Method(5); //No bueno
6
  • 1
    The value of the self property will not be a reference to Class1. It's whatever the value of this is outside the object initializer. Commented Dec 21, 2015 at 16:30
  • 1
    @Liam this is not the function. Commented Dec 21, 2015 at 16:34
  • As noted by Pointy, self : this without a funciton scope gives you whatever this is outside the object, most likely self is the same as window. Commented Dec 21, 2015 at 16:35
  • 1
    You need to use Class1 for self. self is outsite when you call the function you need so you got the window (like this) Commented Dec 21, 2015 at 16:36
  • 2
    Note that there is no inheritance here Commented Dec 21, 2015 at 16:44

2 Answers 2

3

You can fix your example by replacing self with Class1. The line self : this, is setting Class1.self to point to the global object (this when that line is evaluated).

var Class1 = {

    self : this,
    Obj1 : {

        Obj1Method : function () {
            alert("Do something");
        },
        Obj1Method2 : function () {
            alert("Do something else");
        },

        InnerObj1 : {
            InnerNestObj1Method : function (val) {
                alert(val + 2);
            }
        }
    },

    Class1Method2 : function () {
        this.Obj1.Obj1Method2();
    },

    Obj2 : {

        Obj2Method : function (val2) {
            Class1.Obj1.InnerObj1.InnerNestObj1Method(val2);
        },

        Obj2Method2 : function () {
            Class1.Class1Method2();
        }
    }
};

Class1.Obj1.InnerObj1.InnerNestObj1Method(3); //works
Class1.Class1Method2(); //works
Class1.Obj2.Obj2Method2(); //bueno
Class1.Obj2.Obj2Method(5); //bueno

What happens when you do self: this

// If this is running in non strict mode, from the global scope, `this` points
// To the global object because there was no function call setting `this`
var Class1 = {
    self : this,
};

What you need to understand is that this is set by whoever called the function using this. In the example above, there is no caller, so the runtime sets this to point to the global object.

Here's how you could you could make your object a bit more reusable and give yourself a reference to the outer object:

function createClass() {
  var self = {
    Obj1: {

      Obj1Method: function() {
        alert("Do something");
      },
      Obj1Method2: function() {
        alert("Do something else");
      },

      InnerObj1: {
        InnerNestObj1Method: function(val) {
          alert(val + 2);
        }
      }
    },

    Class1Method2: function() {
      self.Obj1.Obj1Method2();
    },

    Obj2: {

      Obj2Method: function(val2) {
        self.Obj1.InnerObj1.InnerNestObj1Method(val2);
      },

      Obj2Method2: function() {
        self.Class1Method2();
      }
    }
  };
  return self;
}

var Class1 = createClass();

Class1.Obj1.InnerObj1.InnerNestObj1Method(3); //works
Class1.Class1Method2(); //works
Class1.Obj2.Obj2Method2(); //works
Class1.Obj2.Obj2Method(5); //works

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks taught me something new.
0

You can do it with Classes:

"use strict"
class Class1 {
  constructor() {
    this.Obj1 = {
      Obj1Method: function() {
        alert("Do something");
      },
      Obj1Method2: function() {
        alert("Do something else");
      },

      InnerObj1: {
        InnerNestObj1Method: function(val) {
          alert(val + 2);
        }
      }
    };
    
    var self = this;
    this.Obj2 = {
      Obj2Method: function(val2) {
        self.Obj1.InnerObj1.InnerNestObj1Method(val2);
      },

      Obj2Method2: function() {
        self.Class1Method2();
      }
    };
  }

  Class1Method2() {
    this.Obj1.Obj1Method2();
  }

};

var c1 = new Class1();
c1.Obj1.InnerObj1.InnerNestObj1Method(3); //works
c1.Class1Method2(); //works
c1.Obj2.Obj2Method(3); //works
c1.Obj2.Obj2Method2(); //works

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.