On Wed, 22 Dec 2004 22:51:27 +0100, Joakim Braun
<> wrote:
> Why doesn't the below code work?
>
> I'm trying to create a global object and set an event handler to one of
> its methods. The function is called, but the object's mTest property is
> undefined.
Read the following slowly. I always find it difficult to word properly.
In the case of using the this operator in a function, it is set by the
caller when the function is called. That is, the caller determines what
this refers to when the call is made.
When you assign a function reference to the property of an object and then
call that function as a method, the this operator will refer to said
object:
var myObject = new Object();
function myFunction() {}
/* myFunction is a property of the global object so when the this
* operator is used, it will refer to the global object.
*/
myFunction();
/* myFunction is now called as a method of the object, myObject.
* Here the this operator will refer to myObject.
*/
myObject.myMethod = myFunction;
myObject.myMethod()
So, when you assign a method from one object to another, the this operator
won't point to the original object, it will point to the one it was called
from.
One way around this is to use a closure and reserve the this operator for
getting the form element.
function Watcher() {
/* Define data here as local variables. */
var test = 'Testing...';
function change() {
/* When this function is called as a result of the change
* event, the this operator will refer to the form control
* that triggered the event.
*/
alert('Changed (test=' + test + ')');
}
this.wire = function(form, element) {
document.forms[form].elements[element].onchange = change;
};
}
var obj = new Watcher();
obj.wire('form1', 'obj1');
[snip]
> function cWatcher(){
>
> this.mTest = "Testing";
> this.wire = cWatcher_Wire;
> this.changeFunc = cWatcher_Changed;
> }
>
>
> function cWatcher_Wire( inFormName,
> inElementName){
>
> document.forms[inFormName].elements[inElementName].onchange =
> this.changeFunc;
>
> }
>
> function cWatcher_Changed(){
>
> alert("Changed, test=" + this.mTest);
>
> }
Those two functions should be added via the prototype:
function cWatcher() {
this.mTest = 'Testing';
}
cWatcher.prototype.wire = function(form, element) {
document.forms[form].elements[element].onchange = this.changeFunc;
};
cWatcher.prototype.changeFunc = function() {
alert("Changed, test=" + this.mTest);
};
Obviously, that will still suffer from the original problems. It was just
a technical suggestion.
[snip]
> window.gWatcher = new cWatcher();
> window.gWatcher.wire("form1","obj1");
The 'window' isn't necessary.
var gWatcher = new cWatcher();
gWatcher.wire('form1', 'obj1');
The var keyword in this instance isn't either; I just think it's good form.
[snip]
Hope that helps,
Mike
--
Michael Winter
Replace ".invalid" with ".uk" to reply by e-mail.