I've always been taught the correct way to simulate a class in JavaScript is by adding methods to the prototype outside the function that will be your class, like this:
function myClass()
{
this.myProp = "foo";
}
myClass.prototype.myMethod = function()
{
console.log(this);
}
myObj = new myClass();
myObj.myMethod();
I've been running into the issue that the this
in my methods resolves to the global Window object, as explained best on quirksmode.
I've tried doing the var that = this;
trick Koch mentions, but since my methods are outside my class, my that
variable is no longer in scope. Perhaps I'm just not understanding it completely.
Is there a way I can create a class in JavaScript where methods are not recreated each implementation and this
will always point to the object?
EDIT:
The simplified code above works but I've had many times where I declare a "class" exactly like above and when I call myObj.myMethod()
, it comes back as a Window
object. I've read over every explanation of this
that I could find, such as the one I linked to and still don't understand why this problem sometimes happens. Any idea of a situation where the code could be written like above and this
would refer to Window
?
Here's the implementation I'm currently having problems with, but when I simplify it down like above into a few lines, I no longer have the problem:
HTML File:
<script type="text/javascript" src="./scripts/class.Database.js"></script>
<script type="text/javascript" src="./scripts/class.ServerFunctionWrapper.js"></script>
<script type="text/javascript" src="./scripts/class.DataUnifier.js"></script>
<script type="text/javascript" src="./scripts/main.js"></script>
class.DataUnifier.js:
function DataUnifier()
{
this._local = new Database();
this._server = new ServerFunctionWrapper();
this.autoUpdateIntervalObj = null;
}
DataUnifier.prototype.getUpdates = function()
{
this._server.getUpdates(updateCommands)
{
console.log(updateCommands);
if (updateCommands)
{
executeUpdates(updateCommands);
}
}
}
//interval is in seconds
DataUnifier.prototype.startAutoUpdating = function(interval)
{
this.stopAutoUpdating();
this.autoUpdateIntervalObj = setInterval(this.getUpdates,interval * 1000);
}
DataUnifier.prototype.stopAutoUpdating = function()
{
if (this.autoUpdateIntervalObj !== null)
{
clearInterval(this.autoUpdateIntervalObj);
this.autoUpdateIntervalObj = null;
}
}
main.js
var dataObj = new DataUnifier();
$(document).ready(function ev_document_ready() {
dataObj.startAutoUpdating(5);
}
I've cut out some code that shouldn't matter but maybe it does. When the page loads and dataObj.startAutoUpdating(5) is called, it breaks at the this.stopAutoUpdating(); line because this
refers to the Window
object. As far as I can see (and according to the link provided), this
should refer to the DataUnifier object. I have read many sources on the this
keyword and don't understand why I keep running into this problem. I do not use inline event registration. Is there any reason code formatted like this would have this problem?
EDIT 2: For those with similar issues, see "The this
problem" half way down the page in this Mozilla docs page: http://developer.mozilla.org/en-US/docs/Web/API/Window.setInterval