I am relatively new to JavaScript, and am having trouble grasping why this error occurs:
TypeError: Attempted to assign to readonly property. MyTimer.js: 35
I understand that this error is displayed because I am using strict mode, but I enabled strict mode to help me debug this Object.
The call to create the MyTimer
singleton is:
var simTimer = new SimTimer();
Then I add a task to be executed in MyTimer
as follows:
var task = function(){
console.log("performing task.");
};
simTimer.addTask(task);
Lastly, this is the MyTimer
Object (line 35 is marked):
var MyTimer = (function () {
"use strict";
// var timer;
var tasks;
/**
* If an instance of MyTimer exists, it will be saved to this variable and returned
* by any subsequent calls to this constructor, thus only one instance (stored in this
* variable) will be accessible.
* @private
*/
var instance;
/**
* Called to initialize this MyTimer Object, or return #instance if it already contains
* an instance of this Object.
*/
function Singleton() {
if (instance) {
return instance;
}
instance = this;
tasks = $.Callbacks();
this.timer = setInterval(function()
{
this.tasks.fire();
}, 1000);//<---- THIS IS LINE 35!
this.addTask = function(task)
{
this.tasks.add(task);
};
this.removeTask = function(task)
{
this.tasks.remove(task);
};
}
//instance accessor
Singleton.getInstance = function () {
return instance || new Singleton();
};
return Singleton();
}());
What have I failed to grasp? I have read through a lot of documentation on Module Patterns, and have successfully written Singletons before - so where do I go wrong here?
** EDIT: **
I was able to get the correct behavior by removing var tasks
, and creating it within Singleton
using this
. The working version of the function now looks like this:
function Singleton() {
if (instance) {
return instance;
}
instance = this;
this.tasks = $.Callbacks();
this.timer = setInterval(function(){
instance.tasks.fire();
}, 1000);
this.removeTask = function(task)
{
instance.tasks.remove(task);
};
this.addTask = function(task)
{
instance.tasks.add(task);
};
}
So I still don't fully understand - why did this change fix it? Was it a scope issue after all?