0

I'm looking for a way to be able to do something like:

new A().b.c()

and have the scope (this) inside the c() method be that of the A prototype.

The only way I've found of doing that is to create the b property inside the A constructor and bind this to the function. I've very much like to be able to do it on the prototype, rather than in the constructor, for the performance benefits it would provide.

Does anyone know how this might be done, or is it simply not possible in Javascript?

Example here:

var A = function () {
  this.isA = true;
}

A.prototype.b = {
  c: function () {
    console.log('isA:', this.isA);
  }
}

// I would like this to result in `isA: true`
new A().b.c();


var M = function () {
  this.isM = true;

  this.b = {
    c: function () {
      console.log('isM', this.isM);
    }.bind(this)
  }
}

// It does here, but involes assignment in the constructor
new M().b.c();

4
  • "have the scope (this) inside the c() method be that of the A prototype.": do you really want this to be the prototype object?? That's weird and would be really bad practice. I guess you mean something else. Can you provide a runnable snippet that outputs the wrong result, with an explanation of what the desired output is? Commented Nov 21 at 15:28
  • "and bind this to the function": which function? Instead of describing your attempt, can you provide the actual code you have used to achieve what you want? I would think you described putting this.b = this in the constructor, but then I don't know what you are talking about when you say you "bind...to the function". Commented Nov 21 at 15:34
  • Apologies if I've got the terminology wrong! This is a little example: jsfiddle.net/gz7sf81p/1 . The first section shows what I would like, the second should how I can make it work, by setting the scope inside the constructor. If that's the only option I have, then so be it (I'm trying to improve the performance of an existing lib, so changing the API isn't an option), but if there is a way to make use of the prototype, I'd very much like to do so. Commented Nov 21 at 15:39
  • "Is it simply not possible in Javascript?" - yes, it is not possible (and usually not desirable to "namespace" methods anyway). The only way is to create a separate b object for every A instance, either in the constructor or dynamically upon access (with a getter on the prototype), that can refer back to the "parent" instance. Commented Nov 21 at 17:13

1 Answer 1

0

Make b a getter rather than a regular property. It then has access to this and can pass it along in the object it returns.

Making c an arrow function will make it preserve its this context from the caller.

var A = function () {
  this.isA = true;
}

Object.defineProperty(A.prototype, "b", {
  get() {
    return {
      c: () => console.log('isA:', this.isA)
    }
  }
});

// I would like this to result in `isA: true`
new A().b.c();

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

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.