2

I have a js object like this:

let service = function () {
  this.a = 100;
}

service.prototype.func = function() {
  console.log(this.a)
}

service.prototype.func2 = function () {
  console.log('func2')
  this.func();
}

service.prototype.obj = {
  m: {
    n: {
      o: function() {
        this.func2();
      },
      p: service.prototype.func2.bind(service.prototype)
    }
  }
}

I want to access the 'a' from o or p, here's the code:

let s = new service();
console.log(s.a)
s.func()
s.func2()
s.obj.m.n.p()
s.obj.m.n.o()

and the output is

100
100
func2
100
func2
undefined
test.js:20
        this.func2();
             ^

TypeError: this.func2 is not a function

Any idea that how I can write o/p properly to perform like func2?

Deo Leung
  • 848
  • 9
  • 9
  • s.obj.m.n.o.call(s) should work. I dont think you can do much with s.obj.m.n.p() as p is returning a function where this is hard bound. – blessanm86 Jan 09 '16 at 01:13
  • Javascript objects have no concept of a parent object so you can't get access to that from within a child unless you specifically store a parent reference in your own property. This is partially because a child object only exists as a reference in a parent property and it could be referenced in many objects. In other words, a child isn't actually owned by any specific parent. It's just a reference in a property and could be a reference in many different objects. – jfriend00 Jan 09 '16 at 03:30

1 Answers1

-1

How about this?

var service = function() {
    this_ = this;
    this.a = 100;
}

service.prototype.func = function() {
    console.log(this.a)
}

service.prototype.func2 = function() {
    console.log('func2')
    this.func();
}

service.prototype.obj = {
    m: {
        n: {
            o: function() {
                this_.func2();
            },
            p: service.prototype.func2.bind(service.prototype)
        }
    }
}

var s = new service();
console.log(s.a)
s.func()
s.func2()
s.obj.m.n.p()
s.obj.m.n.o()

UPDATE:

As pointed out by Jaromanda X, I'm updating the code to do what the OP wanted without defining the global variable (I forgot about that).

var service = function(v) {
    this.a = v;
    this.obj = this.objFunc(this);
}

service.prototype.func = function() {
    console.log(this.a)
}

service.prototype.func2 = function() {
    console.log('func2')
    this.func();
}

service.prototype.objFunc = function(self) {
    return {
        m: {
            n: {
                o: function() {
                    self.func2();
                },
                p: service.prototype.func2.bind(service.prototype)
            }
        }
    };
}


var s = new service(100);
var s2 = new service(200);

s.func();
s2.func();

s.obj.m.n.o());
s2.obj.m.n.o());

The difference between this code and the OP's code is that obj is a property of the each service instance while the OP's code sets the obj as a generic property to the service class.

Also, I set the obj property to call the objFunc class so he can access it as s.obj.m.n.o(). If I didn't he would have to access it as s.obj().m.n.o().

I hope this is what he had in mind and wanted.

Will
  • 1,718
  • 3
  • 15
  • 23
  • `this_` is a global variable - create a second new service and `s.obj.m.n.o()` will not work as you may expect. Also, this does not address the issue with `s.obj.m.n.p()` – Jaromanda X Jan 09 '16 at 01:52
  • @Jaromanda - I wasn't aware that this_ is a global variable, do you have a url that I can read up on this? Thanks – Will Jan 10 '16 at 05:46
  • can you see `this_` declared as `var this_` in a non global scope? Neither can I - there's nothing special about the name `this_` - it's just how you are (not) declaring it that makes it global - You don't need me to send you a link - it's javascript 101 – Jaromanda X Jan 10 '16 at 06:52
  • @JaromandaX - Thanks for pointing that out, I updated the code to support obj property for each instance of the service class. – Will Jan 10 '16 at 20:20