Question

Consider this HTML:

<p>Click me</p>

I would like to write an object with a click handler for each p, but run into the problem that my click handler function could not be found.

This code does not work:

(function(){
    var self = this;

    $("p").each(function(){
        $(this).click(self.myFunction);
    });

    self.myFunction = function(){ alert("myFunction"); }
})();​

When I wrap the click handler assignment in a function it does work:

(function(){
    var self = this;

    $("p").each(function(){
        $(this).click(function(){ self.myFunction(); });
    });

    self.myFunction = function(){ alert("myFunction"); }
})();

Question: Why doesn't $(this).click(self.myFunction) work, but $(this).click(function(){ self.myFunction(); }) does?


Edit: The following code does work:

$("p").click(myFunction);
function myFunction(){ alert("myFunction"); }

Shouldn't this fail as well?


P.S. I got my object working without the need to wrap the function by moving the location of the function:

(function(){
    var self = this;

    self.myFunction = function(){ alert("myFunction"); }

    $("p").each(function(){
        $(this).click(self.myFunction);
    });
})();

I guess the problem is parser related.

Was it helpful?

Solution

In this:

(function(){
    var self = this;

    $("p").each(function(){
        $(this).click(self.myFunction);
    });

    self.myFunction = function(){ alert("myFunction"); }
})();?

The reference is evaluated immediately, and since nothing has been placed in self yet, it fails.

Here:

(function(){
    var self = this;

    $("p").each(function(){
        $(this).click(function(){ self.myFunction(); });
    });

    self.myFunction = function(){ alert("myFunction"); }
})();

The reference is evaluated when the click actually happens, much after self.myfunction is assigned to.

This is in fact not a problem, and an intentional design feature.

In this example:

$("p").click(myFunction);
function myFunction(){ alert("myFunction"); }

The function name is being hoisted to the top of the scope. Since there is nothing dynamic about this function definition (meaning it's not being assigned to an object dynamically), it's available all throughout this scope, from top to bottom.

Functions fill many gaps in JavaScript.

They act as lambdas, modules, methods, functions and probably more that I can't think of right now.

OTHER TIPS

I think you already figured out your problem. At the moment you attach the handlers, self.myFunction isn't defined, so no even handler is attached.

But when you wrap the call like function(){ self.myFunction(); }, then self.myFunction is called at the moment the handler is called, not when it's attached.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top