...

View Full Version : Passing functions as a parameter



Phill
08-10-2006, 11:23 AM
Hi,

Firstly, it's my first post on here so -- hello!

Secondly, I did try to do a search, I couldn't find anything so I apologise if it's been asked a million times before - please feel free to point me in the right direction :)

Thirdly - my question:

I'm creating a remote scripting (ajax) based address book. I'm trying to setup an 'onload' event handler, which points to a class method.

The code is (I'm using prototype, by the way):


var AddressBook = Class.create();
AddressBook.prototype = {
initialize: function() {
// do initialisation stuff here
},

load_addresses: function() {
// make ajax call...
},

load_addresses_cb: function(results) {
// callback function
}
};

var ab = new AddressBook();


The problem comes when I try to setup load_addresses to be the event handler, for example:


window.addEventListener('load', ab.load_addresses, false);

What happens here is that the function is getting executed, but any references to "this" seem to refer to the window rather than the object it's part of.

So, my question is, is there any way of getting "this" to work properly when you're passing functions around? Sorry if this isn't very clear, I'll post with clarification if necessary :)

Thanks!

- Phill

jpalfree
08-10-2006, 06:04 PM
I have not been doing javascript very long, so I don't know prototyping but hopefully i can answer your question regardless.

I had troubles with 'this' aswell. My solution was to make a function to return the actual event listener.
example:


class My_Class
{
//assuming this.variables have been set up and
// this class actually has usefull things in it

function getOnLoadListener()
{

//a variable
var d = this.address;
//a function with a boolean return value...
var func = this.load_addresses;
return function()
{

//will execute this.load_addresses...
// with 'this' meaning a My_Class instance.
return func(d);
}
}
}
//to be used like so. Notice I am executing the function
// 'getOnLoadListener' and it will return a pointer to the
// function that I actually want to be the listener.
window.addEventListener('load', ab.getOnLoadListener(), false);

this works since the variable (pointer) 'func' will always point to your desired function because when it's initialised, 'this' means your My_Class instance, not the window.

Hopefully this isn't overly confusing.
I'd be happy to clarify if you still don't understand.

Phill
08-10-2006, 07:03 PM
Hmm, that is a rather cunning solution!

I'll give it a go and see what happens, thanks :thumb:

In the meantime, if anyone who's used prototype has any pointers as well that'd be cool - I'm sure that I'm doing something wrong, I'm just not sure what :)

jkd
08-10-2006, 11:48 PM
Just do this:


window.addEventListener("load", function() {
ab.load_addresses();
}, false);

Phill
08-11-2006, 12:55 PM
Just do this:


window.addEventListener("load", function() {
ab.load_addresses();
}, false);


Sir, I salute you :cool:

Kor
08-11-2006, 01:04 PM
I doubt it will work in IE.
Why not simply JSON?


window['onload']=function(){
ab.load_addresses()
}

jkd
08-11-2006, 09:33 PM
I doubt it will work in IE.
Why not simply JSON?


window['onload']=function(){
ab.load_addresses()
}


The question has nothing to do with the actual specifics of registering an event listener - it has to do with maintaining the "this" reference inside the load_addresses() method. By passing the method itself as an argument, "this" no longer refers to the particular object the method was a member of, so instead we close the ab variable in an anonymous function scope that calls its load_addresses() method and pass that to the listener registration instead.

Phill
08-11-2006, 11:18 PM
I've found something else that seems to work as well, which is not using prototype for creating classes:


var AddressBook = function() {
var self = this;

var load_addresses = function() {
// you can use "self" to refer to this
}
}

I've found this to work so far :)

Kor
08-12-2006, 10:07 AM
The question has nothing to do with the actual specifics of registering an event listener - it has to do with maintaining the "this" reference inside the load_addresses() method. By passing the method itself as an argument, "this" no longer refers to the particular object the method was a member of, so instead we close the ab variable in an anonymous function scope that calls its load_addresses() method and pass that to the listener registration instead.
Oh, I see



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum