0

I want to make a class in node that runs a set of stages that can be easily added or removed. My current code looks like this:

function MyClass(){
    this._stages = [this.function1, this.function2];
    this._info = {'a':'special object info'};
};
MyClass.prototype.run = function(){
    for(var i = 0; i<this._stages.length; i++){
        this._stages[i]();
    }
};
MyClass.prototype.function1 = function(){
    this.subfunction1();
};
MyClass.prototype.subfunction1 = function(){};

Unfortunately, it seems like putting the function inside the Array messes up their 'parent', and I get an error saying that

TypeError: Object function (query) {
[...long list of elements]
} has no method 'subfunction1'
    at Array.MyClass.function1...

Is there a way to accomplish this by-stage execution without having this happen?

Thanks!

Pablo
  • 10,425
  • 1
  • 44
  • 67

1 Answers1

3

When you put it in the array, it loses its association with this. So, when you then call those functions, they won't have the right this value. You can fix it with .bind():

function MyClass(){
    this._stages = [this.function1.bind(this), this.function2.bind(this)];
    this._info = {'a':'special object info'};
};

A different way to fix it would be to reattach this when you call the functions by using .call() to specifically set the this pointer like this:

MyClass.prototype.run = function(){
    for(var i = 0; i<this._stages.length; i++){
        this._stages[i].call(this);
    }
};

As an explanation, when you do this:

var x = this.function1;
x();

then, all that's in the x variable is a pointer to the function1 function. If you call x(), it will be called without any object reference so this in the function will be either the global object or undefined if running in strict mode. It will not be the desired object.

.bind() creates a stub function that stores the this value and then calls the original function with the right object reference such that the this value is set properly.

If you want a review of how this is set, you can see this answer: When you pass 'this' as an argument

Community
  • 1
  • 1
jfriend00
  • 683,504
  • 96
  • 985
  • 979