Your issue is likely caused by how you are calling your methods. In Javascript, the value of this
is determined by how a method is called, not by how it is declared. You don't show the calling code (where the problem likely is), but if you are calling one of your methods via some sort of callback, then you can easily lose the proper method call that will preserve the value of this
for you. See this other answer for more info on how the value of this
is determined based on how a function is called.
There are many different possible solutions.
Since your object is a singleton (there's only ever just one of them and you've given that one instance a name), I'd suggest that the simplest way to solve your problem is to just refer to the named singleton IntInsert
rather than refer to this
as that will solve any issues with the value of this
in your methods.
You can do that like this:
var state = 0
var IntInsert = //my object that represents a namespace, or a set of functions
{
insertCtrl : function() //main function: it calls the others
{
if (lookup()) return
if (!state) state = 1
var key = document.getElementById("newegg").value
switch(state)
{
case 1:
IntInsert.preInsert(key)
break
case 2:
IntInsert.firstInsert(key)
break
}
},
preInsert : function(key)
{
$("#terminal").css("color", "green")
$("#terminal").text("Inserting element '" + String(key) + "'")
$("#t2cell" + String(cuckoohash.h2(key))).css("background-color", "White")
$("button").prop("disabled", true)
$("input").prop("disabled", true)
$("#nextstep").prop("disabled", false)
state++
},
firstInsert : function(key)
{
key = [document.getElementById("t1").rows[cuckoohash.h1(key)].cells[0].innerHTML, document.getElementById("t1").rows[cuckoohash.h1(key)].cells[0].innerHTML = key][0] // key <-> t1[h1(key)]
if (!key)
{
$("#t1cell" + String(cuckoohash.h1(document.getElementById("t1").rows[cuckoohash.h1(key)].cells[0].innerHTML))).css("background-color", "LightGreen")
IntInsert.finishedInsert()
}
},
finishedInsert : function()
{
$("#terminal").css("color", "green")
$("#terminal").text("Element '" + String(key) + "' inserted")
}
}
Some Other Comments About the Code:
Leaving out semi-colons at the end of each statement may expose you to some accidental bugs. It seems a less than desirable practice to me. The first time you see such a bug, you probably be confused for quite awhile why your code isn't working as intended too.
You can chain in jQuery so instead of this:
$("#terminal").css("color", "green");
$("#terminal").text("Element '" + String(key) + "' inserted");
You can use this:
$("#terminal").css("color", "green").text("Element '" + String(key) + "' inserted");
In Javascript, you rarely need to explicitly cast to a string with String(key)
, so instead of this:
$("#terminal").text("Element '" + String(key) + "' inserted");
You can use this:
$("#terminal").text("Element '" + key + "' inserted");
Adding anything to a string will auto-convert that to a string for your automatically.
You went to the trouble to make a singleton namespace object IntInsert
, yet you declare your variable state
that is not in that namespace object. It seems you should do one of the other, not some odd combination of the two. You either want relevant things in your namespace object or not and such a generically named variable as state
is ripe for a naming conflict. I would think it should be in your object.
It is odd to use a mixture of jQuery selectors like $("#terminal")
and document.getElementById("newegg")
. Code is usually cleaner if you stick with one model or the other. If you're using jQuery for other reasons, then code like:
var key = document.getElementById("newegg").value;
can be this in jQuery:
var key = $("#newegg").val();
In .firstInsert()
, you declare an argument named key
, but then in the first line of code in that method, you assign to key
so the code is just misleading. You declare an argument, but are never using that argument if it is passed in. You should either use the argument or change the key
variable to be just a local variable declaration, not a function argument.
In .finishedInsert()
, you refer to a variable named key
, but there is no such argument or variable by that name.
In .firstInsert()
, this line of code is just bizarre:
var key = [document.getElementById("t1").rows[cuckoohash.h1(key)].cells[0].innerHTML, document.getElementById("t1").rows[cuckoohash.h1(key)].cells[0].innerHTML = key][0];
You appear to be declaring an array with two elements in it, then assigning just the first element to key
. The second element in the array is an assignment to a .innerHTML
property. This is simply a weird and misleading way to write this code. It should be broken up into multiple lines of code.
The first line of code in .firstInsert()
appears to be referring to some sort of global definition of a variable named key
which does not appear anywhere in your code. That is likely a bad idea. The key
you use here should either be in your namespace object or should be passed as an argument to .firstInsert(xxx)
.
Here's a version of your code with as many of those items above fixed/modified and FIXME comments where things are still unexplained:
//my object that represents a namespace, or a set of functions
var IntInsert = {
//main function: it calls the others
state: 0,
insertCtrl: function () {
if (lookup()) return;
if (!IntInsert.state) IntInsert.state = 1;
var key = $("#newegg").val();
switch (IntInsert.state) {
case 1:
IntInsert.preInsert(key);
break;
case 2:
IntInsert.firstInsert(key);
break;
}
},
preInsert: function (key) {
$("#terminal").css("color", "green").text("Inserting element '" + key + "'");
$("#t2cell" + cuckoohash.h2(key)).css("background-color", "White");
$("button").prop("disabled", true);
$("input").prop("disabled", true);
$("#nextstep").prop("disabled", false);
IntInsert.state++;
},
firstInsert: function () {
// key <-> t1[h1(key)]
// FIXME here: There is no variable named key anywhere
document.getElementById("t1").rows[cuckoohash.h1(key)].cells[0].innerHTML = key;
if (!key) {
$("#t1cell" + cuckoohash.h1(document.getElementById("t1").rows[cuckoohash.h1(key)].cells[0].innerHTML)).css("background-color", "LightGreen");
IntInsert.finishedInsert();
}
},
finishedInsert: function () {
// FIXME here: There is no variable named key anywhere
$("#terminal").css("color", "green").text("Element '" + key + "' inserted");
}
};