0

I have a class with multiple methods and properties. One of those methods has a setTimeout() function embedded in it as such:

function myClass() {
    this.some_property = "test";
    this.PrintOnTimeout = function() {
        // I can do var.self = this;
        // but I can't help but feel like that would be inefficient
        setTimeout(function timeoutPrint() {
            // I want to reference this.some_property here.
            // Currently this.some_property returns an error as
            // this refers to PrintOnTimeout() rather than myClass().
        });
    }
}

Apologies in advance if there's an answer up on StackOverflow. I've looked around but pretty much everything I find talks about extended classes and super(). Perhaps super() is the answer here and I'm not understanding it? I'd use global, but I'd prefer to treat each instance of this class as potentially unidentified. So if there's a this.GetMainParent or something... otherwise, I appreciate the uprgrade.

edit 1: The goal isn't to pass 'this' in, which is obvious, but instead to reference the main block (or any particular block, if you set it up so) from anywhere inside a set of nested functions.

edit 2: The arrow function was the solution I needed, as shown by ASDFGerte.

Daniel
  • 37
  • 5
  • *Apologies in advance if there's an answer up on StackOverflow.* There are. Many, in fact. :-) –  Aug 17 '16 at 05:55
  • I'm not sure what the goal of your comment was. I explained immediately after that I wasn't sure how to look it up and all I could find were things talking about class extension and super(). In fact, this question was flagged as a duplicate of another, when the question this is flagged as being the same as does not have the same solution. I'm not trying to pass 'this' in, I'm trying to reference the main block from anywhere inside a function (or nested function (or nested function)). And the arrow function is the solution here. – Daniel Aug 22 '16 at 15:47
  • 1
    [Arrow functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions) in JS, in advance of arguments of how _could_ have done this, were created exactly for this purpose. Effectively declaring the same value multiple times is wasteful. Arrow functions FTW. – Daniel Aug 22 '16 at 15:51
  • "*I can't help but feel like that would be inefficient*" - it's not. It's a basic closure, just like any of the other solutions. – Bergi Aug 22 '16 at 16:00

1 Answers1

1

You can use an arrow function to bind this, use bind(this) or close over a local variable that stores the property.

Note that unless you bind this to every function involved, you need to make sure all related functions are always called in the correct context, otherwise you are binding the nested functions to the wrong this:

function a(){
  this.x = "hi";
  this.y = function() {
    setTimeout(() => { console.log(this.x); }, 100);
  };
}

let obj = new a();
let outside = obj.y;
obj.y(); //y is being called with this === obj
outside(); //y is being called with this depending on strict mode, window or undefined.
ASDFGerte
  • 4,695
  • 6
  • 16
  • 33