Click here to Skip to main content
15,892,927 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
JavaScript
Clock = function (ele)
{
	if (ele)
	{
		if (typeof ele == 'string')
		{
			this.node = document.getElementById(ele);
		}
		else
		{
			this.node = ele;
		}
	}
	else
	{
		throw new Error('')
	}
};

Clock.prototype = {
	getTime: function ()
	{
		var d = new Date;
		var s = d.getSeconds().toString(), m = d.getMinutes().toString(),
			pm = d.getHours() > 12,
			h = (pm ? (d.getHours() - 12) : d.getHours()).toString();
		return ((h.length === 2) ? (Number.h.charAt(1)) : ('0' + h)) + ':' +
			   ((m.length === 2) ? m : ('0' + m)) + ':' +
			   ((s.length === 2) ? s : ('0' + s)) + ' ' +
				(pm ? 'PM' : 'AM');
	},
	tick: function () { this.node.innerText = this.getTime() },
	start: function ()
	{
		this.interval = setInterval(this.tick, 1000);
	},
	stop: function ()
	{
		clearInterval(this.interval)
	}
};


This code is a class called Clock that is used with the "new" keyword. I've also defined several properties of it using its prototype property, and when the "start" function is called it sets a timer to call the "tick" function every 1 second. The issue I'm facing is the keyword "this" doesn't refer to my class but instead the "Window" object, so I need a way to reference the "node" and "getTime" properties inside a new instance of my class without using the this keyword. Any advice?

What I have tried:

I know I can create a global variable and reference that inside any of the methods but that defeats the purpose of having a class to be used with a constructor.
Posted
Updated 18-Mar-16 18:02pm

Too bad you are not using strict mode; then what you think is the [Window] object referenced by this would be the object undefined, which is much better for safe programming. Also, strict mode would not allow your Clock = function () with missing var keyword.
So, my first advice: during development, always start all your scripts with
JavaScript
"use strict";

See also: Strict mode - JavaScript | MDN[^].

If you really want, you can switch "strict" off when your development is done.

Your other problem is the way of thinking. You say "…without using the this keyword", as if "this" was the hassle. It's not a hassle, it's a feature you really need to understand. First of all, you should understand that "this" in JavaScript is very different from "this" in OOP language; and this is so, first of all, because of the nature of functions which are first-class citizen objects. You make some simple mistake which I cannot see because you did not show some relevant part of code. If something does not work for you, instead of getting rid of it, you should try to understand it. But I can explain what can go on.

And, finally, your problem is: you are writing too much code before you sort out some fundamentals. Let me shorten it down to show what you could observe:
JavaScript
function f() { writeLine(this); }

var Clock = function () {
	this.node = 2;
}

Clock.prototype = {
	start: function ()
	{
		writeLine(this.node);
		f();
	},
};

function f() { writeLine(this); }

var cl = new Clock();
cl.start();
In this code sample, writeLine is my debug/playground function. If you call start, you will see that "this" is really reference your Clock object, because you reference it inside a function which is an instance member of this object. When you call f (or setInterval, "this" would be undefined, because these functions are as much of objects as any other objects; and these objects are not properties of another object; they are on the top level. And, in your code shown, there are no such "this" cases; you have only this.tick and this.interval. First will work as the clock object property, and, unfortunately, you did not show where you define interval. If it is not defined, as shown in your code fragment, this is the real problem, and "this" is not guilty. :-)

—SA
 
Share this answer
 
In the end I changed my code so that the start function went like this:
JavaScript
var t = this;
this.interval = setInterval(this.tick, 1000, t);


and the tick function accepted a parameter to replace the "this" keyword. Like this:
JavaScript
tick: function (t)
{
    t.node.innerText = t.getTime()
}
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900