Reputation: 2575
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
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
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
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