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

'this' and prototypes

P: n/a
I have some code that's structured a bit like this:

Con = function(choice, el) {
this.choice = choice;
document.getElementById(el).onclick = this.choiceClicked;
}

Con.prototype.choiceClicked = function() {
alert(this.choice);
}

foo = new Con(1,"bar")

Why is it when I click on the element "bar" this choice alerts as
'undefined'? In the prototype 'this' is the element clicked and not what
is was expecting (the object 'foo'). I'd like the 'this' in the
prototype to refer to 'foo': is there some way to do this?

Andrew Poulos
Sep 15 '05 #1
Share this Question
Share on Google+
7 Replies


P: n/a
To understand what is happening read:

http://www.brockman.se/writing/metho...nces.html.utf8

The simplest way I've found to fix it is to use the prototype.js
library:

http://prototype.conio.net/

If you do this:

document.getElementById(el).onclick =
this.choiceClicked.bindAsEventListener(this);

'this' will be what you expect.

Hope this helps,
Cathy

Sep 15 '05 #2

P: n/a
EventListener <Ev***********@gmail.com> wrote:
Someone else wrote (context restored)
Con = function(choice, el) {
this.choice = choice;
document.getElementById(el).onclick = this.choiceClicked;
}


I'm extremely curious as to why this doesn't work as one would intend.
Clearly "this" in the first line refers to the Con object; it
therefore seems that it should have been possible for the ECMA script
designers to differentiate

document.getElementById(el).onclick = this.choiceClicked;

from

document.getElementById(el).onclick = 'this.choiceClicked()';

Is the basic issue that event attributes may only be references to
global functions? Would

var a={};
a.foo=function() {alert('foo');}

document.getElementById( 'bar' ).onclick=a.foo;

work as intended?

--
Christopher Benson-Manica | I *should* know what I'm talking about - if I
ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
Sep 15 '05 #3

P: n/a


Christopher Benson-Manica wrote:

it
therefore seems that it should have been possible for the ECMA script
designers to differentiate

document.getElementById(el).onclick = this.choiceClicked;

from

document.getElementById(el).onclick = 'this.choiceClicked()';


There is certainly a difference between the result of the right hand
side expression in the first assigment and the one in the second assigment.
The first yields a function object, the second a string.
And the function object the first right hand side expression yields is
not bound to the this object, it is simply a function object. The this
object only exists when a function is called.

That is what the ECMAScript specification deals with. Event handlers and
HTML element attributes are not in any way part of that specification or
what its designers dealt with.

--

Martin Honnen
http://JavaScript.FAQTs.com/
Sep 15 '05 #4

P: n/a
Martin Honnen <ma*******@yahoo.de> wrote:
There is certainly a difference between the result of the right hand
side expression in the first assigment and the one in the second assigment.
The first yields a function object, the second a string.


Well darn it. I was and am aware of the fact that 'this' refers to
the element that generated the event in an event handler, so I really
can't explain how I managed to produce that post. Time to make some
more coffee.

--
Christopher Benson-Manica | I *should* know what I'm talking about - if I
ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
Sep 15 '05 #5

P: n/a
On 15/09/2005 14:38, Andrew Poulos wrote:

[snip]
Con = function(choice, el) {
this.choice = choice;
document.getElementById(el).onclick = this.choiceClicked;
}

Con.prototype.choiceClicked = function() {
alert(this.choice);
}


[snip]

This issue has been discussed many, many times in the past. The most
recent I recall is

Subject: .addEventListener() not finding the right object method
Date: 2005/08/26 14:37 GMT
Message ID: 11**********************@g44g2000cwa.googlegroups. com
<URL:http://groups.google.co.uk/group/comp.lang.javascript/browse_thread/thread/e8702c77bcd68fc8/45eed8c571173a3e>

where I referenced

Subject: How to understand the javascript class model?
Date: 2005/08/25 02:28 GMT
Message ID: de***********@mail.cn99.com
<URL:http://groups.google.co.uk/group/comp.lang.javascript/browse_thread/thread/9b041b9103b6de0f/2065870c97d74b50>

from the day before.

Mike

--
Michael Winter
Prefix subject with [News] before replying by e-mail.
Sep 15 '05 #6

P: n/a
Andrew Poulos wrote:
I have some code that's structured a bit like this:

Con = function(choice, el) {
this.choice = choice;
document.getElementById(el).onclick = this.choiceClicked;
}

Con.prototype.choiceClicked = function() {
alert(this.choice);
}

foo = new Con(1,"bar")

Why is it when I click on the element "bar" this choice alerts as
'undefined'? In the prototype 'this' is the element clicked and not what
is was expecting (the object 'foo'). I'd like the 'this' in the
prototype to refer to 'foo': is there some way to do this?


I learned to use closures to do this.

function Con(choice, e1)
{
this.choice = choice;
document.getElementById(e1).onclick = Con.createClickHandler(this)
}

function _Con_createClickHandler(obj)
{
return function(event)
{
obj.choiceClicked();
}
}

function _Con_choiceClicked()
{
alert(this.choice);
}

Con.prototype.choiceClicked = _Con_choiceClicked;
Con.createClickHandler = _Con_createClickHandler;

Sep 16 '05 #7

P: n/a
On 16/09/2005 11:27, Robert wrote:

[snip]
function Con(choice, e1)
{
this.choice = choice;
document.getElementById(e1).onclick = Con.createClickHandler(this)
}

function _Con_createClickHandler(obj)
{
return function(event)
{
obj.choiceClicked();
}
}
Incidentally, this will still create the memory leak that you've harped
on about recently. :P

In the factory function, there is an object reference to a DOM object,
obj. This object will (eventually) have a property that is a reference
to a function object. This function object has, in its scope chain, a
reference to the original DOM object.

This is exactly the same process that you've seen elsewhere. The only
difference is that the assignment is deferred to another execution context.

The discussions I linked to mention workable alternatives, as will
previous threads in this group.
function _Con_choiceClicked()
{
alert(this.choice);
}

Con.prototype.choiceClicked = _Con_choiceClicked;
Con.createClickHandler = _Con_createClickHandler;


Don't create unnecessary intermediary globals. Instead, assign the
function object to the property directly:

Con.prototype.choiceClicked = function() {
alert(this.choice);
};

Mike

--
Michael Winter
Prefix subject with [News] before replying by e-mail.
Sep 22 '05 #8

This discussion thread is closed

Replies have been disabled for this discussion.