Attach a class method to event handler

U

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...
 
P

Peter Michaux

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...[/QUOTE]

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
 
T

Thomas 'PointedEars' Lahn

Peter said:
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?[/QUOTE][/QUOTE]

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);
}
}
};
[QUOTE]
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 );
}
}[/QUOTE]

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

MyClass.prototype.doSomething = function( ) {};
MyClass.prototype.assignFun = function( )
{
document.getElementById('my_div').onclick =
MyClass.prototype.doSomethingWith;
}[/QUOTE]

It is getting worse.  Now the method of the prototype object will be called
as a method of the Global Object.
[QUOTE]
It may be a mistake to be thinking in terms of "MyClass" as JavaScript
doesn't have classes.[/QUOTE]

That, at least, is correct.


PointedEars
 
R

RobG

On May 30, 10:35 am, Thomas 'PointedEars' Lahn <[email protected]>
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;
 
P

Peter Michaux

Peter said:
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?[/QUOTE][/QUOTE]

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);
}
}
};
[QUOTE]
if you want to avoid the closure then don't create one with selfObj.[/QUOTE]
[QUOTE]
MyClass.prototype.doSomething = function( ) {};
MyClass.prototype.assignFun = function( )
{
document.getElementById('my_div').onclick = function ( e )
{
MyClass.prototype.doSomethingWith( e || event );
}
}[/QUOTE]

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

It is getting worse.  Now the method of the prototype object will be called
as a method of the Global Object.[/QUOTE]

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
 
T

Thomas 'PointedEars' Lahn

Peter said:
Peter said:
[...]
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
 
L

Laurent vilday

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 !
 
U

Ugo

[simple-js]
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...
 
P

Peter Michaux

Peter said:
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
 
T

Thomas 'PointedEars' Lahn

Peter said:
Peter said:
On May 29, 5:35 pm, Thomas 'PointedEars' Lahn <[email protected]>
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.
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.)
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
 
P

Peter Michaux

Peter said:
Peter Michaux wrote:
On May 29, 5:35 pm, Thomas 'PointedEars' Lahn <[email protected]>
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.
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.)
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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top