By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
459,575 Members | 1,413 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 459,575 IT Pros & Developers. It's quick & easy.

'this', event handlers, and namespaces

P: n/a
Hi,

Consider the following simplified code in which Foo is used as a
'namespace':

var Foo = {
doAlert: function() {
alert('hello');
},
myEventHandler: function(e) {
this.doAlert();
}
}

document.addEventListener('keydown', Foo.doAlert, false);
This gives me an error because when responding to the event, the
object 'this' is the document because that's what I've attached the
event handler to. I know I could just replace 'this' with "Foo.' but
my understanding is that I take a performance hit every time I make
such a global reference. And, since I'm developing a large web
application in Javascript, I'd like to avoid unnecessary performance
hits when possible.

Anyone know what is the accepted standard of what to do in this case?

Thanks!
Jeff
Jun 27 '08 #1
Share this Question
Share on Google+
10 Replies


P: n/a
On May 16, 9:27 am, Jeff Bigham <jeffrey.big...@gmail.comwrote:
Hi,

Consider the following simplified code in which Foo is used as a
'namespace':

var Foo = {
doAlert: function() {
alert('hello');
},
myEventHandler: function(e) {
this.doAlert();
}

}

document.addEventListener('keydown', Foo.doAlert, false);

This gives me an error because when responding to the event, the
object 'this' is the document because that's what I've attached the
event handler to. I know I could just replace 'this' with "Foo.' but
my understanding is that I take a performance hit every time I make
such a global reference. And, since I'm developing a large web
application in Javascript, I'd like to avoid unnecessary performance
hits when possible.

Anyone know what is the accepted standard of what to do in this case?
Try this thread:

Subject: pseudo-namespacing in JavaScript
<URL:
http://groups.google.com.au/group/co...45e485506c4a92
>

--
Rob
Jun 27 '08 #2

P: n/a
jdd
On May 15, 7:27*pm, Jeff Bigham <jeffrey.big...@gmail.comwrote:
Hi,

Consider the following simplified code in which Foo is used as a
'namespace':

var Foo = {
* doAlert: function() {
* * alert('hello');
* },
* myEventHandler: function(e) {
* * this.doAlert();
* }

}

document.addEventListener('keydown', Foo.doAlert, false);

This gives me an error because when responding to the event, the
object 'this' is the document because that's what I've attached the
event handler to. *I know I could just replace 'this' with "Foo.' but
my understanding is that I take a performance hit every time I make
such a global reference. *And, since I'm developing a large web
application in Javascript, I'd like to avoid unnecessary performance
hits when possible.

Anyone know what is the accepted standard of what to do in this case?

Thanks!
Jeff
I don't know if it's the accepted standard of what to do, but you
could do something like:

var Foo = {
* doAlert: function() {
* * alert('hello');
* },
* myEventHandler: (function(t) {
that = t;
return function(e) {
* * that.doAlert();
};
})(this)
}

I don't think this would be avoiding a performance hit though, and you
probably shouldn't listen to my advice as I'm still a bit green on
javascript. Additionally, I think the proper solution depends on what
exactly you're trying to do.
Jun 27 '08 #3

P: n/a
Jeff Bigham wrote:
Consider the following simplified code in which Foo is used as a
'namespace':

var Foo = {
doAlert: function() {
alert('hello');
},
myEventHandler: function(e) {
this.doAlert();
}
}

document.addEventListener('keydown', Foo.doAlert, false);
Probably you meant to write

document.addEventListener('keydown', Foo.myEventHandler, false);

instead, as there is no `this' in Foo.doAlert().
This gives me an error because when responding to the event, the
object 'this' is the document because that's what I've attached
the event handler to.
_added_ event _listener_ to

This is a FAQ, and the solution is simple:

document.addEventListener(
'keydown',
function(e) { Foo.myEventHandler(e) },
false);

That said, by convention only names of properties that refer to
constructors, and identifiers of constant primitive values, should begin
with a capital letter.
I know I could just replace 'this' with "Foo.' but my understanding
is that I take a performance hit every time I make such a global reference.
That is correct, as no identifier resolution is required for the `this'
value of the execution context. However, the evaluation loop would be very
short; the main issue here is maintainability: You really do not want to do
search and replace when you have to rename `Foo' (and you should do that).
And, since I'm developing a large web application in Javascript, I'd
like to avoid unnecessary performance hits when possible.
Good thinking, though.
Anyone know what is the accepted standard of what to do in this case?
There is no accepted standard about it, only common sense guided by the text
of the ECMAScript Specification and by the reality of its implementations.
PointedEars
--
realism: HTML 4.01 Strict
evangelism: XHTML 1.0 Strict
madness: XHTML 1.1 as application/xhtml+xml
-- Bjoern Hoehrmann
Jun 27 '08 #4

P: n/a
jdd wrote:
On May 15, 7:27 pm, Jeff Bigham <jeffrey.big...@gmail.comwrote:
>Consider the following simplified code in which Foo is used as a
'namespace':

var Foo = {
doAlert: function() {
alert('hello');
},
myEventHandler: function(e) {
this.doAlert();
}
}

document.addEventListener('keydown', Foo.doAlert, false);

This gives me an error because when responding to the event, the
object 'this' is the document because that's what I've attached the
event handler to. [...]

Anyone know what is the accepted standard of what to do in this case?

I don't know if it's the accepted standard of what to do, but you
could do something like:

var Foo = {
doAlert: function() {
alert('hello');
},
myEventHandler: (function(t) {
that = t;
return function(e) {
that.doAlert();
};
})(this)
}
This code does not address the problem at all. In the above scenario, the
`myEventHandler' property would be assigned a reference to a Function object
that calls the doAlert() method of the *Global Object* (or the object
referenced by the `that' property of an object in the scope chain, see
below) instead of the object referred to by `Foo'. A TypeError exception on
event is likely as the Global Object (or that object) is unlikely to have a
method of that name. It is semantically equal to

that = this;
var Foo = {
doAlert: function() {
alert('hello');
},
myEventHandler: function(e) {
that.doAlert();
};
};

Also, the undeclared `that' identifier is inherently error-prone.

Please trim your quotes as recommended e.g. in the FAQ Notes.
PointedEars
--
Use any version of Microsoft Frontpage to create your site.
(This won't prevent people from viewing your source, but no one
will want to steal it.)
-- from <http://www.vortex-webdesign.com/help/hidesource.htm>
Jun 27 '08 #5

P: n/a
jdd
On May 15, 10:14*pm, Thomas 'PointedEars' Lahn <PointedE...@web.de>
wrote:
This code does not address the problem at all. . . *
You are correct, thanks for the explanation.
Jun 27 '08 #6

P: n/a
On May 16, 1:27*am, Jeff Bigham <jeffrey.big...@gmail.comwrote:
Hi,

Consider the following simplified code in which Foo is used as a
'namespace':

var Foo = {
* doAlert: function() {
* * alert('hello');
* },
* myEventHandler: function(e) {
* * this.doAlert();
* }

}

document.addEventListener('keydown', Foo.doAlert, false);

This gives me an error because when responding to the event, the
object 'this' is the document because that's what I've attached the
event handler to. *I know I could just replace 'this' with "Foo.' but
my understanding is that I take a performance hit every time I make
such a global reference. *And, since I'm developing a large web
application in Javascript, I'd like to avoid unnecessary performance
hits when possible.

Anyone know what is the accepted standard of what to do in this case?

Thanks!
Jeff
<html lang="en"><head>
<title>untitled</title></head><body>
<script>
var c= ": No closure";
(function () {
var d, e, c= ": anon f closure !";;
var y= function (p) { return document.createElement(p) };
var z= function (p) {
document.body.appendChild(y('br'));
return document.body.appendChild(p);
};
var x= function (p) { (z(y('text'))).innerHTML= p };

var foo= function (e) {
var c= ": foo closure !";
var me= arguments.callee;
me.doAlert= function() { x(this.src+': onClick'+c) };
var doAlert= function() { x(this.src+': onMouseUp'+c) };

//function object method : foo.doAlert()
e.onclick= me.doAlert;
//foo local var:
e.onmouseup= doAlert;
//anonymous function:
e.onmouseover= function () { x(this.src+': onMouseOver'+c) };
return e;
};

foo.too= function () { x(this.src+': onMouseOut'+c) };

(e= foo(z(y('img')))).src="http://tinyurl.com/6nhepj"
//anonimous function object method 2:
e.onmouseout= foo.too;
(d=z(y('img'))).src="http://tinyurl.com/5ehxv5"
//anonimous function object method 2:
d.onmouseout= foo.too;
d.onmouseover= e.onmouseover;
})();
</script></body></html>
Jun 27 '08 #7

P: n/a
On May 16, 1:27*am, Jeff Bigham <jeffrey.big...@gmail.comwrote:
Hi,

Consider the following simplified code in which Foo is used as a
'namespace':

var Foo = {
* doAlert: function() {
* * alert('hello');
* },
* myEventHandler: function(e) {
* * this.doAlert();
* }

}

document.addEventListener('keydown', Foo.doAlert, false);

This gives me an error because when responding to the event, the
object 'this' is the document because that's what I've attached the
event handler to. *I know I could just replace 'this' with "Foo.' but
my understanding is that I take a performance hit every time I make
such a global reference. *And, since I'm developing a large web
application in Javascript, I'd like to avoid unnecessary performance
hits when possible.

Anyone know what is the accepted standard of what to do in this case?

Thanks!
Jeff
<html lang="en"><head>
<title>untitled</title></head><body>
<script>
var c= ": No closure";
(function () {
var d, e, c= ": anon f closure !";;
var y= function (p) { return document.createElement(p) };
var z= function (p) { return document.body.appendChild(p) };
var x= function (p) {
z(y('br'));
(z(y('text'))).innerHTML= p;
};

var foo= function (e) {
var c= ": foo closure !";
var me= arguments.callee;
me.doAlert= function() { x(this.src+': onClick'+c) };
var doAlert= function() { x(this.src+': onMouseUp'+c) };

//function object method : foo.doAlert()
e.onclick= me.doAlert;
//foo local var:
e.onmouseup= doAlert;
//anonymous function:
e.onmouseover= function () { x(this.src+': onMouseOver'+c) };
return e;
};

foo.too= function () { x(this.src+': onMouseOut'+c) };

(e= foo(z(y('img')))).src="http://tinyurl.com/6nhepj"
//anonimous function object method 2:
e.onmouseout= foo.too;

(d=z(y('img'))).src="http://tinyurl.com/5ehxv5"
//anonimous function object method 2:
d.onmouseout= function () { x(this.src+': onMouseOut'+c) };
d.onmouseover= function () { x(this.src+': onMouseOver'+c) };
d.onclick= function() { x(this.src+': onClick'+c) };
d.onmouseup= function () { x(this.src+': onMouseUp'+c) };

(d=z(y('img'))).src="http://tinyurl.com/5j84u6"
//anonimous function object method 2:
d.onmouseout= e.onmouseout;
d.onmouseover= e.onmouseover;
d.onclick= e.onclick;
d.onmouseup= e.onmouseup;

})();
</script></body></html>
Jun 27 '08 #8

P: n/a
Jorge wrote:
On May 16, 1:27 am, Jeff Bigham <jeffrey.big...@gmail.comwrote:
>Anyone know what is the accepted standard of what to do in this case?
[...]

<html lang="en"><head>
<title>untitled</title></head><body>
<script>
var c= ": No closure";
(function () {
var d, e, c= ": anon f closure !";;
var y= function (p) { return document.createElement(p) };
var z= function (p) { return document.body.appendChild(p) };
var x= function (p) {
z(y('br'));
(z(y('text'))).innerHTML= p;
};

var foo= function (e) {
var c= ": foo closure !";
var me= arguments.callee;
me.doAlert= function() { x(this.src+': onClick'+c) };
var doAlert= function() { x(this.src+': onMouseUp'+c) };

//function object method : foo.doAlert()
e.onclick= me.doAlert;
[...]
Sorry, this does not come even close to an approach that could make it to
standard procedure, much less to the standards-compliant approach that the
OP was following already. It is not even Valid markup to begin with:

http://validator.w3.org/
PointedEars
--
var bugRiddenCrashPronePieceOfJunk = (
navigator.userAgent.indexOf('MSIE 5') != -1
&& navigator.userAgent.indexOf('Mac') != -1
) // Plone, register_function.js:16
Jun 27 '08 #9

P: n/a
Anyone know what is the accepted standard of what to do in this case?

There is no accepted standard about it, only common sense guided by the text
of the ECMAScript Specification and by the reality of its implementations.
Thanks. What you suggested worked well.

-Jeff
PointedEars
--
realism: HTML 4.01 Strict
evangelism: XHTML 1.0 Strict
madness: XHTML 1.1 as application/xhtml+xml
-- Bjoern Hoehrmann
Jun 27 '08 #10

P: n/a
* Jeff Bigham wrote in comp.lang.javascript:
>Consider the following simplified code in which Foo is used as a
'namespace':

var Foo = {
doAlert: function() {
alert('hello');
},
myEventHandler: function(e) {
this.doAlert();
}
}

document.addEventListener('keydown', Foo.doAlert, false);
You would have to call the event handler method 'handleEvent' and pass
the object rather than the function to addEventListener, i.e., like so:

var Foo = {
doAlert: function() {
alert('hello');
},
handleEvent: function(e) {
this.doAlert();
}
}

document.addEventListener('keydown', Foo, false);

With your approach `this` should always be bound to e.currentTarget.
--
Björn Höhrmann · mailto:bj****@hoehrmann.de · http://bjoern.hoehrmann.de
Weinh. Str. 22 · Telefon: +49(0)621/4309674 · http://www.bjoernsworld.de
68309 Mannheim · PGP Pub. KeyID: 0xA4357E78 · http://www.websitedev.de/
Jun 27 '08 #11

This discussion thread is closed

Replies have been disabled for this discussion.