LDK
LDK

Reputation: 2575

Javascript: adding methods using prototype descriptor

Code:

Sorter.prototype.init_bubblesort = function(){
  console.log(this.rect_array);
  this.end = this.rect_array.length;
  this.bubblesort();
}

Sorter.prototype.init = function(array,sort_type){
  this.rect_array = array;
  this.init_bubblesort();
}

The code above works as expected, but when I change the init function to:

Sorter.prototype.init = function(array,sort_type){
  var sort_types = {'bubblesort':this.init_bubblesort,
                'quicksort':this.init_quicksort,
                'liamsort':this.init_liamsort};
  this.rect_array = array;
  sort_types[sort_type]();
}

the init_bubblesort function results in an error saying this.rect_array is undefined. I'm trying to wrap my head around why init_bubblesort no longer has access to its instance's variables.

Upvotes: 2

Views: 276

Answers (3)

Matthew Flaschen
Matthew Flaschen

Reputation: 284826

You need to use call to specify the implicit parameter (this).

Sorter.prototype.init = function(array,sort_type){
  var sort_types = {'bubblesort':this.init_bubblesort,
                'quicksort':this.init_quicksort,
                'liamsort':this.init_liamsort};
  this.rect_array = array;
  sort_types[sort_type].call(this);
}

Otherwise, there is no object associated with the init_bubblesort method.

For the setTimeout, do:;

var self = this;
setTimeout(function(){sort_types[sort_type].call(self);}, 1000);

In the callback, this will refer to the window, so we create a separate variable (self), which will be closed in.

Upvotes: 1

Christian C. Salvadó
Christian C. Salvadó

Reputation: 827416

Matthew got your problem, but looking at your code, the sort_types object seems a bit redundant to me, if you are only using it to map a function "foo" with the prefix "init_foo", you could do something simple this:

Sorter.prototype.init = function(array,sort_type){
  this.rect_array = array;
  this["init_"+sort_type](); // the `this` value will work without problems
}

Upvotes: 1

Sean Kinsey
Sean Kinsey

Reputation: 38046

The reason why you are getting this error is that this referred to inside the functions are resolved into the object which the method is a property of.

In the first case this is the Sorter object, in the second it is the sort_types object, and of course, these are not the same.

The easiest way to do this would therefor be the following.

Sorter.prototype.init = function (array, sort_type) {
    var sort_types = {
        'bubblesort': "init_bubblesort",
        'quicksort': "init_quicksort",
        'liamsort': "init_liamsort"
    };
    this.rect_array = array;
    this[sort_types[sort_type]]();
}

As an alternative, call could be used to 'change' the context of the executed method.

And to answer the comment on the other question, if you need to defer the execution of the sort, the you can do this

Sorter.prototype.init = function (array, sort_type) {
    var sort_types = {
        'bubblesort': "init_bubblesort",
        'quicksort': "init_quicksort",
        'liamsort': "init_liamsort"
    };
    this.rect_array = array;
    var that = this;
    window.setTimeout(function(){
        that[sort_types[sort_type]]();
    }, 80);
}

In this case the context is kept the same.

Upvotes: 1

Related Questions