Re: javascript custom object event handling and this
From: Jonathan (j)
Date: 10/11/04
- Next message: name: "Re: Problem with javascript in IE on Windows XP 2002 SP2"
- Previous message: Don: "Communicating to server .php without using <form>"
- In reply to: Richard Cornford: "Re: javascript custom object event handling and this"
- Next in thread: Chris Barber: "Re: javascript custom object event handling and this"
- Messages sorted by: [ date ] [ thread ]
Date: Sun, 10 Oct 2004 20:15:43 -0500
Thanks, Richard. Your explanation was very enlightening. I am going to
thoroughly read into the topic of Closures. This will help me in my quest to
better understand the OO concepts and caveats of javascript.
When my little 'project' is complete, I will post it here for critique.
Thanks again,
Jonathan
"Richard Cornford" <Richard@litotes.demon.co.uk> wrote in message
news:ckbm0u$i2g$1$8302bc10@news.demon.co.uk...
> Chris Barber wrote:
>> The method you are using to assign the event handler actually
>> creates a copy of the event handler function and thus the
>> this keyword is now referring to the object that called the
>> event handler.
>
> That isn't true. The initial act of assigning a reference to a function
> object (resulting from the evaluation of a function expression) to a
> property of the object's prototype is the only point at which a new
> function object is created. The later act of assigning the value of
> the - HandleKeyDown - property of an object instance to the event
> handling property of the document does exactly, and only, that. i.e.:
> The value of instance's - HandleKeyDown - is a reference to a function
> object and it is that reference that is assigned to the event handling
> property of the document, both properties then refer to the same (and
> only) function object.
>
> The value associated with the - this - keyword when that function object
> is executed is determined by how the function is called. If it is called
> as a method of an object (any object) then - this - refers to that
> object. If it were not called as a method of an object (but directly
> executed) then - this - would refer to the global object.
>
> All javascript functions are function objects and exhibit the same
> behaviour with regard to the - this - keyword regardless of how and
> where they were created.
>
> The problem is that once the reference to the function object has been
> assigned to the even handling property of the document, when the event
> handler is executed it is called as a method of the document and -
> this - is thus a reference to the document.
>
>> You can do this:
>>
>> <begin code>
>>
>> //object
>> function MyObj()
>> {
>> this.Prop = "MyObj.Prop";
>> }
>>
>> MyObj.prototype.HandleKeyDown = function()
>> {
>> // if left arrow key is pressed, alert MyObj.Prop
>> if (event.keyCode == 37) alert(this.Prop);
>> }
>>
>> var o = new MyObj();
>>
>> window.document.onkeydown =
>> New Function("return o.HandleKeyDown();")
> <snip>
>
> That unambiguously is creating a new function object. And it assumes
> that - o - is a stable global variable to which a reference to an
> instance of the right type of object has been assigned. It also places
> the code that creates the global reference, and assigns the event
> handler, outside of the object.
>
> That isn't a problem for a small-ish page specific script, and this
> looks like a smallish page specific script because attempting to use an
> instance method of the - MyObject - object as the onkeydown event
> handler suggests that no more than one instance of - MyObject - will
> ever be used (as there is only one - document.onkeydown - handler
> available).
>
> In a more general implementation, with the intention of creating more OO
> code that was easily re-usable, it is common to need to be in a position
> to call an object instance method (often with an event handler) without
> any regard for the actions of code that is external to the object. Thus
> the object needs to be able to refer to its own instance in a way that
> is anonymous (or apparently anonymous to external code). Usually with
> the code that does the assigning of the event handler moved inboard (and
> a reference to the object to which the handler is to be attached passed
> in as a parameter to the constructor or a method call).
>
> A number of techniques (and variations) can be used to associate an
> object instance with an event handler anonymously of external code. One
> of the simplest is for the constructor to independently arrange a global
> reference to its object instances and store sufficient information in
> each object for it to be able to resolve a reference to itself
> globally:-
>
> Record the current length of the globally accessible array of instances
> as the - this.index - property of the constructed object (so that this
> object instance can look itself up in the array) and assign a reference
> to the constructed object to the array element at that index:-
>
> function MyObj(){
> /* Record the current length of the globally accessible array
> of instances as the - this.index - property of the
> constructed object (so that this object instance can look
> itself up in the array) and assign a reference to the
> constructed object to the array element at that index:-
> */
> MyObj.instances[(this.index = MyObj.instances.lenght)] = this;
> this.Prop = "MyObj.Prop";
> }
> /* Create an array that can store individual object
> instance references:-
> */
> MyObj.instances = [];
>
> MyObj.prototype.HandleKeyDown = function(e){
> e = e||window.event;
> // if left arrow key is pressed, alert MyObj.Prop
> if (e.keyCode == 37) alert(this.Prop);
> }
>
> This approach lends itself to the use of the Function constructor to
> create the actual event handler, and to objects that want to use
> document.write to insert HTML source that refers back to the individual
> object instance. For example:-
>
> MyObj.prototype.attachDocKeyHandler = function(doc){
> /* Create a new event handling function that calls an instance
> method of this object without any regard for how external
> code is using this object instance.
> */
> doc.onkeydown = new Function(
> 'e',
> ('MyObj.instances['+this.index+'].HandleKeyDown(e)')
> );
> }
>
> - or:-
>
> MyObj.prototype.writeInputField = function(){
> /* Write an input field that has a onkeydown handler that calls
> a method of this object instance.
> */
> document.write(
> ('<input type="text" value="" onkeydonw="'+
> 'MyObj.instances['+this.index+'].HandleKeyDown(event)'+
> '">')
> );
> }
>
> Most other techniques for associating object instances with event
> handlers are closure-based, but they tend to be truly anonymous, and
> lend themselves to circumstances where constructing string references
> would be inconvenient (such as when creating DOM elements) and direct
> object and function references more useful. Closures are big subject and
> allow many variations on specific techniques. A specific example, and an
> explanation of closures can be found at:-
>
> <URL: http://jibbering.com/faq/faq_notes/closures.html >
>
> Richard.
>
>
- Next message: name: "Re: Problem with javascript in IE on Windows XP 2002 SP2"
- Previous message: Don: "Communicating to server .php without using <form>"
- In reply to: Richard Cornford: "Re: javascript custom object event handling and this"
- Next in thread: Chris Barber: "Re: javascript custom object event handling and this"
- Messages sorted by: [ date ] [ thread ]
Relevant Pages
|