Connecting Tech Pros Worldwide Forums | Help | Site Map

Dynamically name an instance of an Object

CES
Guest
 
Posts: n/a
#1: Dec 17 '05
All,
I'm sorry but I still don't get this!!

I'm trying to use a variable that is passed into a function to to dynamically name an instance of an Object(). I've created a Timer() Object that seems to work just fine... the problem is I can't figure out how to pass in an instance name into setTimer() to create a new instance of Timer() object?? My ultimate goal is to have multiple instances of the Timer() Object running at once. While the code below works it only allows me to create 1 instance of the Timer() Object with the name of tmp.

I've tried adding both:
var tmp = divId; // This is what I would like...
var tmp = "tmp"; // But even this throws an error...
But these will throw a "tmp is undefined" error and points to line 1 chr 1? Unfortunately my knowledge of JavaScript is so limited I just don't see the problem?

Any help on this wold be greatly appreciated... Thanks in advance. - CES

function setTimer(status,divId){
//var tmp = divId; This will throws an error!!
if(status=="start"){
//var tmp = divId; This will throws an error!!
tmp = new Timer(divId); // Why will var tmp = new Timer(divId); throws an error here??
tmp.startTimer();
}else if(typeof tmp == "object"){
tmp.stopTimer();
tmp = ''; // Why does tmp = null; throw an error isn't object = null, the proper way of disposing of an object??
}
}

function Timer(name){
var secs = 10;
var timerID = null;
var timerRunning = false;
var delay = 1000;

if(typeof Timer.initialized == "undefined"){
Timer.prototype.startTimer = function (){
this.stopTimer();
this.counterStatus();
}
Timer.prototype.stopTimer = function (){
if(timerRunning != null){
clearTimeout(timerID);
this.timerRunning = false;
secs = 10;
}
}
Timer.prototype.counterStatus = function (){
if (secs==0){
this.stopTimer();
document.getElementById("id_" + name).style.backgroundColor = "green";
}else{
secs = secs - 1;
timerRunning = true;
document.getElementById("id_" + name).innerHTML = secs;
timerID = self.setTimeout(name + ".counterStatus()", delay);
}
}
Timer.initialized = true;
}
}

</script>
<div id="id_tmp" style="width:100px; height:100px; background-color:blue;" onmouseover="setTimer('','tmp')" onmouseout="setTimer('start','tmp')"" />

Daniel Kirsch
Guest
 
Posts: n/a
#2: Dec 19 '05

re: Dynamically name an instance of an Object


CES wrote:[color=blue]
> function setTimer(status,divId){
> //var tmp = divId; This will throws an error!![/color]

Well, you create a local variable and expect it to be global by
referencing it by name in your timer script

timerID = self.setTimeout(name + ".counterStatus()", delay);
^^^^
And even it it would be a global variabel you always overwrite it here.

The statement itself will not throw any error and it's not necessary to
set a new variable to hold the same value allready given in divId.
The error was thrown by the given line (check out your script with
Firefox which will show you much more detailed and exact error messages
in it's JavaScript Console.

[color=blue]
> if(status=="start"){
> //var tmp = divId; This will throws an error!![/color]

same as above.

[color=blue]
> tmp = new Timer(divId); // Why will var tmp = new
> Timer(divId); throws an error here??[/color]

dito.

[color=blue]
> tmp.startTimer();
> }else if(typeof tmp == "object"){
> tmp.stopTimer();
> tmp = ''; // Why does tmp = null; throw an error isn't
> object = null, the proper way of disposing of an object??[/color]

use the delete operator or at least set it to null. "" (or '') is an
empty string which is not the same as null.

[color=blue]
> function Timer(name){
> var secs = 10;
> var timerID = null;
> var timerRunning = false;
> var delay = 1000;
>
> if(typeof Timer.initialized == "undefined"){
> Timer.prototype.startTimer = function (){
> this.stopTimer();
> this.counterStatus();
> }[/color]

I really don't see a reason why you define the prototype methods within
the main function. This migh lead to unwanted memory leaks caused by so
called closures (A function that is defined within another function and
may reference all variables of the outer function).

Maybe something like this is what you are looking for:

function setTimer(status,divId){
if (typeof Timer[divId] == "object" && typeof
Timer[divId].stopTimer == "function")
Timer[divId].stopTimer();
if(status=="start"){
Timer[divId] = new Timer(divId);
Timer[divId].startTimer();
}
}

function updateTimer(name) {
if (Timer[name])
Timer[name].counterStatus();
}

function Timer(name){
this.secs = 10;
this.name = name;
this.timerID = null;
this.timerRunning = false;
this.delay = 1000;
Timer[name] = this;
}

Timer.prototype = {

startTimer : function (){
this.stopTimer();
this.counterStatus();
},

stopTimer : function (){
if(this.timerRunning != null){
clearTimeout(this.timerID);
this.timerRunning = false;
this.secs = 10;
}
},

counterStatus : function (){
var elm = document.getElementById("id_" + this.name);
if (!elm) return;
if (this.secs==0){
this.stopTimer();
elm.style.backgroundColor = "green";
}else{
this.secs--;
this.timerRunning = true;
elm.innerHTML = this.secs;
this.timerID = setTimeout("updateTimer('" + this.name+ "')",
this.delay);
}
}
};

Daniel
CES
Guest
 
Posts: n/a
#3: Dec 19 '05

re: Dynamically name an instance of an Object


Daniel Kirsch wrote:[color=blue]
> CES wrote:[color=green]
>> function setTimer(status,divId){
>> //var tmp = divId; This will throws an error!![/color]
>
> Well, you create a local variable and expect it to be global by
> referencing it by name in your timer script
>
> timerID = self.setTimeout(name + ".counterStatus()", delay);
> ^^^^
> And even it it would be a global variabel you always overwrite it here.
>
> The statement itself will not throw any error and it's not necessary to
> set a new variable to hold the same value allready given in divId.
> The error was thrown by the given line (check out your script with
> Firefox which will show you much more detailed and exact error messages
> in it's JavaScript Console.
>
>[color=green]
>> if(status=="start"){
>> //var tmp = divId; This will throws an error!![/color]
>
> same as above.
>
>[color=green]
>> tmp = new Timer(divId); // Why will var tmp = new
>> Timer(divId); throws an error here??[/color]
>
> dito.
>
>[color=green]
>> tmp.startTimer();
>> }else if(typeof tmp == "object"){
>> tmp.stopTimer();
>> tmp = ''; // Why does tmp = null; throw an error isn't
>> object = null, the proper way of disposing of an object??[/color]
>
> use the delete operator or at least set it to null. "" (or '') is an
> empty string which is not the same as null.
>
>[color=green]
>> function Timer(name){
>> var secs = 10;
>> var timerID = null;
>> var timerRunning = false;
>> var delay = 1000;
>>
>> if(typeof Timer.initialized == "undefined"){
>> Timer.prototype.startTimer = function (){
>> this.stopTimer();
>> this.counterStatus();
>> }[/color]
>
> I really don't see a reason why you define the prototype methods within
> the main function. This migh lead to unwanted memory leaks caused by so
> called closures (A function that is defined within another function and
> may reference all variables of the outer function).
>
> Maybe something like this is what you are looking for:
>
> function setTimer(status,divId){
> if (typeof Timer[divId] == "object" && typeof Timer[divId].stopTimer
> == "function")
> Timer[divId].stopTimer();
> if(status=="start"){
> Timer[divId] = new Timer(divId);
> Timer[divId].startTimer();
> }
> }
>
> function updateTimer(name) {
> if (Timer[name])
> Timer[name].counterStatus();
> }
>
> function Timer(name){
> this.secs = 10;
> this.name = name;
> this.timerID = null;
> this.timerRunning = false;
> this.delay = 1000;
> Timer[name] = this;
> }
>
> Timer.prototype = {
>
> startTimer : function (){
> this.stopTimer();
> this.counterStatus();
> },
>
> stopTimer : function (){
> if(this.timerRunning != null){
> clearTimeout(this.timerID);
> this.timerRunning = false;
> this.secs = 10;
> }
> },
>
> counterStatus : function (){
> var elm = document.getElementById("id_" + this.name);
> if (!elm) return;
> if (this.secs==0){
> this.stopTimer();
> elm.style.backgroundColor = "green";
> }else{
> this.secs--;
> this.timerRunning = true;
> elm.innerHTML = this.secs;
> this.timerID = setTimeout("updateTimer('" + this.name+ "')",
> this.delay);
> }
> }
> };
>
> Daniel[/color]

Daniel,

While I digest your code I was wondering what kind of statement/form is this:

Timer.prototype = {startTimer : function (){this.stopTimer();this.counterStatus();}, //Other methods}

The "value : function()" makes it look like a switch but it obviously not??

I'm assuming that:
Timer.prototype = {startTimer : function(){
is equivalent to:
Timer.prototype.startTimer = function (){

Sorry for the real stupid question. Thanks in advance. - CES




Dave Anderson
Guest
 
Posts: n/a
#4: Dec 19 '05

re: Dynamically name an instance of an Object


Daniel Kirsch wrote:[color=blue]
>
> function Timer(name){
> this.secs = 10;
> this.name = name;
> this.timerID = null;
> this.timerRunning = false;
> this.delay = 1000;
> Timer[name] = this;
> }
>
> Timer.prototype = {
>
> startTimer : function (){
> this.stopTimer();
> this.counterStatus();
> },
>
> stopTimer : function (){
> if(this.timerRunning != null){
> clearTimeout(this.timerID);
> this.timerRunning = false;
> this.secs = 10;
> }
> },
>
> counterStatus : function (){
> var elm = document.getElementById("id_" + this.name);
> if (!elm) return;
> if (this.secs==0){
> this.stopTimer();
> elm.style.backgroundColor = "green";
> }else{
> this.secs--;
> this.timerRunning = true;
> elm.innerHTML = this.secs;
> this.timerID = setTimeout("updateTimer('" + this.name+ "')",
> this.delay);
> }
> }
> };[/color]

Is it even necessary to use the prototype object in this case? Seems to me
this type of construction should suffice:

function Timer(name){
this.secs = 10;
this.name = name;
this.timerID = null;
this.timerRunning = false;
this.delay = 1000;
Timer[name] = this;
this.startTimer = function() { ... }
this.stopTimer = function() { ... }
this.counterStatus = function() { ... }
}


--
Dave Anderson

Unsolicited commercial email will be read at a cost of $500 per message. Use
of this email address implies consent to these terms. Please do not contact
me directly or ask me to contact you directly for assistance. If your
question is worth asking, it's worth posting.


Lasse Reichstein Nielsen
Guest
 
Posts: n/a
#5: Dec 19 '05

re: Dynamically name an instance of an Object


CES <none@none.com> writes:
[color=blue]
> While I digest your code I was wondering what kind of statement/form is this:
>
> Timer.prototype = {startTimer : function (){this.stopTimer();this.counterStatus();}, //Other methods}
>
> The "value : function()" makes it look like a switch but it obviously not??[/color]

It's not. It's part of the notation for an object literal. It has
the form
{ name : value , name2 : value2, <etc> }
[color=blue]
> I'm assuming that:
> Timer.prototype = {startTimer : function(){
> is equivalent to:
> Timer.prototype.startTimer = function (){[/color]

Almost, but not entirely.

In the first case, you create a new object, using an object literal
to define it, and then assigns that to Timer.prototype. That overrides
the existing value of Timer.prototye.

In the second case you merely add one property to the existing object
value of Timer.prototype. It retains its existing properties, including
Timer.prototype.constructor (with the default value Timer).

/L
--
Lasse Reichstein Nielsen - lrn@hotpop.com
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
'Faith without judgement merely degrades the spirit divine.'
Daniel Kirsch
Guest
 
Posts: n/a
#6: Dec 21 '05

re: Dynamically name an instance of an Object


Dave Anderson wrote:[color=blue]
> Is it even necessary to use the prototype object in this case? Seems to me
> this type of construction should suffice:
>
> function Timer(name){
> this.secs = 10;
> this.name = name;
> this.timerID = null;
> this.timerRunning = false;
> this.delay = 1000;
> Timer[name] = this;
> this.startTimer = function() { ... }
> this.stopTimer = function() { ... }
> this.counterStatus = function() { ... }
> }[/color]

Yes, but you create unnecessary closures (functions within a function)
again and your methods will be created for each instance you create.
Using the prototype will create the method only one time and all
instances reference that prototype method, so less memory is needed.

Daniel
Daniel Kirsch
Guest
 
Posts: n/a
#7: Dec 21 '05

re: Dynamically name an instance of an Object


CES wrote:[color=blue]
> While I digest your code I was wondering what kind of statement/form is
> this:
>
> Timer.prototype = {startTimer : function
> (){this.stopTimer();this.counterStatus();}, //Other methods}[/color]

It's the short way of defining an object with defined properties or (in
this case) methods.

Creating an Object:

var obj = new Object();

or shorter

var obj = {};

Adding properties to that object:

var obj = new Object();
obj.prop1 = "value";
obj.prop2 = 5;

or shorter

var obj = {prop1 : "value", prop2 : 5};

But not only simple properties can be set but also methods or subobjects.

var obj = {prop1 = "value",
meth1 : function(msg) {
if (msg)
alert(msg);
}
};

That's the same as using

var obj = new Object();
obj.prop1 = "value";
obj.meth = function(msg) {
if (msg)
alert(msg);
};


Using that object notation for the prototype saves a lot of typing and a
couple of characters which results in a smaller document size and
therefore can be downloaded faster. (all occurences of
"Object.prototype." can be avoided)

Daniel
Daniel Kirsch
Guest
 
Posts: n/a
#8: Dec 21 '05

re: Dynamically name an instance of an Object


Daniel Kirsch wrote:[color=blue]
> var obj = {prop1 = "value",[/color]
^
This must read

var obj = {prop1 : "value",

Daniel
Thomas 'PointedEars' Lahn
Guest
 
Posts: n/a
#9: Dec 21 '05

re: Dynamically name an instance of an Object


Daniel Kirsch wrote:
[color=blue]
> Creating an Object:
>
> var obj = new Object();
>
> or shorter
>
> var obj = {};[/color]

With the (weak) provision that the latter (Object object literals) requires
JavaScript 1.3 (NN4.06), JScript 3.0 (IE4, IIS4) or an ECMAScript 3
conforming implementation (such as the Opera implementation since Opera
6.0), while the former is supported ever since.
[color=blue]
> var obj = {prop1 = "value",[/color]

You corrected this typo yourself in news:dob4eq$kvl$02$1@news.t-online.com
[color=blue]
> meth1 : function(msg) {
> if (msg)
> alert(msg);
> }
> };
>
> That's the same as using
>
> var obj = new Object();
> obj.prop1 = "value";
> obj.meth = function(msg) {[/color]
^
Typo, should be `obj.meth1'.


Regards,
PointedEars
Closed Thread