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

Attach a class method to event handler

P: n/a
Ugo
Hi guys,

until now I make so:

[html]
<div id="my_div"><!-- content --></div>

[simple-js]
MyClass.prototype.doSomething = function( ) {};
MyClass.prototype.assignFun = function( )
{
var selfObj = this;
document.getElementById('my_div').onclick = function ( e )
{
selfObj.doSomethingWith( e || event );
}
}

How do I avoid the closure of my object reference?
And MyClass is not a Singleton...
Jun 27 '08 #1
Share this Question
Share on Google+
10 Replies


P: n/a
On May 29, 8:36 am, Ugo <priv...@nospam.itwrote:
Hi guys,

until now I make so:

[html]
<div id="my_div"><!-- content --></div>

[simple-js]
MyClass.prototype.doSomething = function( ) {};
MyClass.prototype.assignFun = function( )
{
var selfObj = this;
document.getElementById('my_div').onclick = function ( e )
{
selfObj.doSomethingWith( e || event );
}

}

How do I avoid the closure of my object reference?
And MyClass is not a Singleton...
if you want to avoid the closure then don't create one with selfObj.

MyClass.prototype.doSomething = function( ) {};
MyClass.prototype.assignFun = function( )
{
document.getElementById('my_div').onclick = function ( e )
{
MyClass.prototype.doSomethingWith( e || event );
}

}

or perhaps even

MyClass.prototype.doSomething = function( ) {};
MyClass.prototype.assignFun = function( )
{
document.getElementById('my_div').onclick =
MyClass.prototype.doSomethingWith;
}
It may be a mistake to be thinking in terms of "MyClass" as JavaScript
doesn't have classes.

Peter
Jun 27 '08 #2

P: n/a
Peter Michaux wrote:
On May 29, 8:36 am, Ugo <priv...@nospam.itwrote:
>until now I make so:

[html]
<div id="my_div"><!-- content --></div>

[simple-js]
MyClass.prototype.doSomething = function( ) {};
MyClass.prototype.assignFun = function( )
{
var selfObj = this;
document.getElementById('my_div').onclick = function ( e )
{
selfObj.doSomethingWith( e || event );
}
}

How do I avoid the closure of my object reference?
MyClass.prototype.assignFun = function() {
document.getElementById('my_div').onclick = (function(o) {
return function(e) {
o.doSomethingWith(e || window.event);
};
})(this);
};

That said, you should avoid mixing "DOM Level 0" and DOM Level 2 features in
one statement; at least you should feature-test both before you mix them.
Such Reference Worms[tm] are error-prone anyway. Consider this (still
error-prone because of the partially proprietary, apparently untestable
approach):

MyClass.prototype.assignFun = function() {
if (isMethod(document, "getElementById"))
{
var target = document.getElementById('my_div');
if (target)
{
target.onclick = (function(o) {
return function(e) {
o.doSomethingWith(e || window.event);
};
})(this);
}
}
};
>And MyClass is not a Singleton...

if you want to avoid the closure then don't create one with selfObj.

MyClass.prototype.doSomething = function( ) {};
MyClass.prototype.assignFun = function( )
{
document.getElementById('my_div').onclick = function ( e )
{
MyClass.prototype.doSomethingWith( e || event );
}
}
While this is not the least equivalent to the original, `MyClass' is the
bound "variable" of the closure then.
or perhaps even

MyClass.prototype.doSomething = function( ) {};
MyClass.prototype.assignFun = function( )
{
document.getElementById('my_div').onclick =
MyClass.prototype.doSomethingWith;
}
It is getting worse. Now the method of the prototype object will be called
as a method of the Global Object.
It may be a mistake to be thinking in terms of "MyClass" as JavaScript
doesn't have classes.
That, at least, is correct.
PointedEars
--
var bugRiddenCrashPronePieceOfJunk = (
navigator.userAgent.indexOf('MSIE 5') != -1
&& navigator.userAgent.indexOf('Mac') != -1
) // Plone, register_function.js:16
Jun 27 '08 #3

P: n/a
On May 30, 10:35 am, Thomas 'PointedEars' Lahn <PointedE...@web.de>
wrote:
[...]
That said, you should avoid mixing "DOM Level 0" and DOM Level 2 features in
one statement; at least you should feature-test both before you mix them.
Such Reference Worms[tm] are error-prone anyway. Consider this (still
error-prone because of the partially proprietary, apparently untestable
approach):

MyClass.prototype.assignFun = function() {
if (isMethod(document, "getElementById"))
{
var target = document.getElementById('my_div');
if (target)
{
target.onclick = (function(o) {
return function(e) {
o.doSomethingWith(e || window.event);
};
})(this);
}
Doesn't that create a circular reference to the DOM element referenced
by target? Should that be avoided by using, at this point:

target = null;

}
};

--
Rob
Jun 27 '08 #4

P: n/a
On May 29, 5:35 pm, Thomas 'PointedEars' Lahn <PointedE...@web.de>
wrote:
Peter Michaux wrote:
On May 29, 8:36 am, Ugo <priv...@nospam.itwrote:
until now I make so:
[html]
<div id="my_div"><!-- content --></div>
[simple-js]
MyClass.prototype.doSomething = function( ) {};
MyClass.prototype.assignFun = function( )
{
var selfObj = this;
document.getElementById('my_div').onclick = function ( e )
{
selfObj.doSomethingWith( e || event );
}
}
How do I avoid the closure of my object reference?

MyClass.prototype.assignFun = function() {
document.getElementById('my_div').onclick = (function(o) {
return function(e) {
o.doSomethingWith(e || window.event);
};
})(this);
};

That said, you should avoid mixing "DOM Level 0" and DOM Level 2 features in
one statement; at least you should feature-test both before you mix them.
Such Reference Worms[tm] are error-prone anyway. Consider this (still
error-prone because of the partially proprietary, apparently untestable
approach):

MyClass.prototype.assignFun = function() {
if (isMethod(document, "getElementById"))
{
var target = document.getElementById('my_div');
if (target)
{
target.onclick = (function(o) {
return function(e) {
o.doSomethingWith(e || window.event);
};
})(this);
}
}
};
And MyClass is not a Singleton...
if you want to avoid the closure then don't create one with selfObj.
MyClass.prototype.doSomething = function( ) {};
MyClass.prototype.assignFun = function( )
{
document.getElementById('my_div').onclick = function ( e )
{
MyClass.prototype.doSomethingWith( e || event );
}
}

While this is not the least equivalent to the original, `MyClass' is the
bound "variable" of the closure then.
or perhaps even
MyClass.prototype.doSomething = function( ) {};
MyClass.prototype.assignFun = function( )
{
document.getElementById('my_div').onclick =
MyClass.prototype.doSomethingWith;
}

It is getting worse. Now the method of the prototype object will be called
as a method of the Global Object.
It wasn't clear what the code in the original post was doing or even
if the doSomething function uses "this". Without a complete question a
complete answer is not possible.

[snip]

Peter
Jun 27 '08 #5

P: n/a
Peter Michaux wrote:
On May 29, 5:35 pm, Thomas 'PointedEars' Lahn <PointedE...@web.de>
wrote:
>Peter Michaux wrote:
>>[...]
MyClass.prototype.doSomething = function( ) {};
MyClass.prototype.assignFun = function( )
{
document.getElementById('my_div').onclick = function ( e )
{
MyClass.prototype.doSomethingWith( e || event );
}
}

While this is not the least equivalent to the original, `MyClass' is the
bound "variable" of the closure then.
>>or perhaps even

MyClass.prototype.doSomething = function( ) {};
MyClass.prototype.assignFun = function( )
{
document.getElementById('my_div').onclick =
MyClass.prototype.doSomethingWith;
}
It is getting worse. Now the method of the prototype object will be called
as a method of the Global Object.

It wasn't clear what the code in the original post was doing or even
if the doSomething function uses "this". Without a complete question a
complete answer is not possible.
You are winding around the issue.

It does not matter whether the purpose of the code was clear (to you) or
not; using the `this' reference in a prototype method and using the
reference to the prototype object there are clearly not the same thing, nor
are assigning the reference to a prototype method versus assigning a
reference to a Function object that calls this prototype method (as
inherited through the prototype chain). So it cannot be expected to have
the same outcome, and is therefore not the least equivalent to one another.

Host objects aside, consider this (in Fx 2.0.0.14):

function MyObject(answer) {
this.bar = function() {
window.alert(answer);
};
}

MyObject.prototype.foo = function() {
// 42
this.bar();

// 23,function MyObject...
MyObject.prototype.bar();

var f = MyObject.prototype.bar;

// 23,[Window]
f();
};

MyObject.prototype.bar = function() {
window.alert([23, this.constructor]);
}

(new MyObject(42)).foo();

Trimming quotes a bit more would increase the chance of your postings being
recognized in the future.
PointedEars
--
var bugRiddenCrashPronePieceOfJunk = (
navigator.userAgent.indexOf('MSIE 5') != -1
&& navigator.userAgent.indexOf('Mac') != -1
) // Plone, register_function.js:16
Jun 27 '08 #6

P: n/a
Thomas 'PointedEars' Lahn a écrit :
Trimming quotes a bit more would increase the chance of your postings being
recognized in the future.
FFS, who do you think you are ? Go to hell !

--
laurent
Jun 27 '08 #7

P: n/a
Ugo
>>[simple-js]
>>MyClass.prototype.doSomething = function( ) {};
MyClass.prototype.assignFun = function( )
{
var selfObj = this;
document.getElementById('my_div').onclick = function ( e )
{
selfObj.doSomethingWith( e || event );
}
}

How do I avoid the closure of my object reference?

MyClass.prototype.assignFun = function() {
document.getElementById('my_div').onclick = (function(o) {
return function(e) {
o.doSomethingWith(e || window.event);
};
})(this);
};

That said, you should avoid mixing "DOM Level 0" and DOM Level 2 features in
one statement;
i.e.?
Where did I mix?
So, if I am not mistaken, you make a closure too:
your approach is more elegant, but you close the parameter "o" of the
anonymous function, or not?
at least you should feature-test both before you mix them.
it was only example...
Jun 27 '08 #8

P: n/a
On May 30, 4:43 am, Thomas 'PointedEars' Lahn <PointedE...@web.de>
wrote:
Peter Michaux wrote:
On May 29, 5:35 pm, Thomas 'PointedEars' Lahn <PointedE...@web.de>
wrote:
Peter Michaux wrote:
[...]
MyClass.prototype.doSomething = function( ) {};
MyClass.prototype.assignFun = function( )
{
document.getElementById('my_div').onclick = function ( e )
{
MyClass.prototype.doSomethingWith( e || event );
}
}
While this is not the least equivalent to the original, `MyClass' is the
bound "variable" of the closure then.
>or perhaps even
>MyClass.prototype.doSomething = function( ) {};
MyClass.prototype.assignFun = function( )
{
document.getElementById('my_div').onclick =
MyClass.prototype.doSomethingWith;
}
It is getting worse. Now the method of the prototype object will be called
as a method of the Global Object.
It wasn't clear what the code in the original post was doing or even
if the doSomething function uses "this". Without a complete question a
complete answer is not possible.

You are winding around the issue.
No I'm not.
It does not matter whether the purpose of the code was clear (to you) or
not;
If the question is not clear then many answers are possible.
using the `this' reference in a prototype method
There was no use of "this" in the original question.
and using the
reference to the prototype object there are clearly not the same thing, nor
are assigning the reference to a prototype method versus assigning a
reference to a Function object that calls this prototype method (as
inherited through the prototype chain). So it cannot be expected to have
the same outcome, and is therefore not the least equivalent to one another.
But it may have acceptable outcome. The question was not clear. That
was actually one point I was making with my original answer.

[snip]
Peter
Jun 27 '08 #9

P: n/a
Peter Michaux wrote:
On May 30, 4:43 am, Thomas 'PointedEars' Lahn <PointedE...@web.de>
wrote:
>Peter Michaux wrote:
>>On May 29, 5:35 pm, Thomas 'PointedEars' Lahn <PointedE...@web.de>
wrote:
Peter Michaux wrote:
[...]
MyClass.prototype.doSomething = function( ) {};
MyClass.prototype.assignFun = function( )
{
document.getElementById('my_div').onclick = function ( e )
{
MyClass.prototype.doSomethingWith( e || event );
}
}

While this is not the least equivalent to the original, `MyClass' is the
bound "variable" of the closure then.
[...]
It wasn't clear what the code in the original post was doing or even
if the doSomething function uses "this". Without a complete question a
complete answer is not possible.
You are winding around the issue.

No I'm not.
You are overlooking something important, then.
>It does not matter whether the purpose of the code was clear (to you) or
not;

If the question is not clear then many answers are possible.
True. However, a good answer would at least provide an equivalent solution
to the presented problem (which was, without doubt, how to avoid closures).
Yours did not provide an equivalent solution. (Mine did provide a
equivalent solution, but maybe no solution to the OP's problem. Insofar
both of us might have failed to provide a good answer.)
>using the `this' reference in a prototype method

There was no use of "this" in the original question.
My example shows that this does not matter. Literally.

I have trimmed the quote more so that you may see the point more easily.
PointedEars
--
Anyone who slaps a 'this page is best viewed with Browser X' label on
a Web page appears to be yearning for the bad old days, before the Web,
when you had very little chance of reading a document written on another
computer, another word processor, or another network. -- Tim Berners-Lee
Jun 27 '08 #10

P: n/a
On May 30, 12:33 pm, Thomas 'PointedEars' Lahn <PointedE...@web.de>
wrote:
Peter Michaux wrote:
On May 30, 4:43 am, Thomas 'PointedEars' Lahn <PointedE...@web.de>
wrote:
Peter Michaux wrote:
On May 29, 5:35 pm, Thomas 'PointedEars' Lahn <PointedE...@web.de>
wrote:
Peter Michaux wrote:
[...]
MyClass.prototype.doSomething = function( ) {};
MyClass.prototype.assignFun = function( )
{
document.getElementById('my_div').onclick = function ( e )
{
MyClass.prototype.doSomethingWith( e || event );
}
}
>>While this is not the least equivalent to the original, `MyClass' is the
bound "variable" of the closure then.
[...]
It wasn't clear what the code in the original post was doing or even
if the doSomething function uses "this". Without a complete question a
complete answer is not possible.
You are winding around the issue.
No I'm not.

You are overlooking something important, then.
It does not matter whether the purpose of the code was clear (to you) or
not;
If the question is not clear then many answers are possible.

True. However, a good answer would at least provide an equivalent solution
to the presented problem (which was, without doubt, how to avoid closures).
Yours did not provide an equivalent solution. (Mine did provide a
equivalent solution, but maybe no solution to the OP's problem. Insofar
both of us might have failed to provide a good answer.)
using the `this' reference in a prototype method
There was no use of "this" in the original question.

My example shows that this does not matter. Literally.

I have trimmed the quote more so that you may see the point more easily.
I can see that you have done a very nice job at trimming the quotes.

Peter

[snip] <-- see how I trimmed your signature.

Jun 27 '08 #11

This discussion thread is closed

Replies have been disabled for this discussion.