Judismar Junior Judismar Junior - 7 months ago 9
Javascript Question

A bug involving JavaScript's object structure

I'm writing a whole client-side system in JavaScript. I have about 4 .js files, but there is no need to post code from them, nor the html.

Anyway, before explaining the problem, I'll try to explain what is the code about, and the code itself.

Basically, it's a finite state machine in a design level. For now, I only have 3 states: the initial, a transition and the final state (the state machine, for now, is a queue). The code is 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:
this.preInsert(key)
break
case 2:
this.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")
this.finishedInsert()
}
},

finishedInsert : function()
{
$("#terminal").css("color", "green")
$("#terminal").text("Element '" + String(key) + "' inserted")
}
}


In the line this.firstInsert(key), a bug happens. Firebug tells me this: TypeError: this.firstInsert is not a function. This is weird, given that it's defined as a function and Firebug itself represents it as a function in it's high-level panel.

If I take the function out of the object and use it as a global function, there is no error at all. That's why I believe the whole semantics of the code can be ignored in order to answer my question, which is: why is this happening inside the object? What is it that I'm missing?

Answer

The reason you are seeing the error is most likely because at runtime 'this' is changing to an object that doesn't have your function. Try restructuring your code and "closing" on this like this:

var IntInsert = function()
{
    var self = this;
    ...
    var insertCtrl = function() //main function: it calls the others
    {
        ... 
        case 2:
            self.firstInsert(key)
            break
        ...
    }
    ...

    var firstInsert = function(key)
    {
        ...
    }

    return {
        insertCtrl: insertCtrl,
        firstInsert: firstInsert
    }
}

... or something similar that would fit your needs.

Comments