Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In javascript functions, can you set this.function = function?

I have run into this jquery plugin and i quite understand how this works:

$.functionone = function(){

    function setOptions(newOptions){
        ...
    }
    this.setOptions = setOptions;
}

What i dont understand is what does this actually do? this.setOptions = setOptions can you call a function without parenthesis? What is the relationship between this.setOptions and setOptions by itself?

like image 479
anthonypliu Avatar asked Dec 29 '22 12:12

anthonypliu


1 Answers

Functions in JavaScript are objects like (nearly) everything else. When you do this:

this.setOptions = setOptions;

you're not calling the setOptions function, you're just assigning a reference to the function to a property, exactly like setting a property to any other object, like this:

var dt;
dt = new Date();
this.today = dt;

With functions, you'd do this so you can later call the function via the property (which sets up the this value to be the object the property's on, which is handy). It's a bit clearer what's going on if you use a different name for the property than for the function:

function functionName() { ... }   // Declares the function
this.propertyName = functionName; // Sets the property
functionName();                   // Calls the function (with `this` = the global object ["window", on browsers])
this.propertyName();              // Also calls the function (but with `this` = the object the property's on)

The pattern you identified, declaring a function and then separately setting a reference to it on an object, is frequently used to make sure the resulting function has a name. You can create a function and bind it to a property like this:

this.setOptions = function() {
    ...
};

...but then the function doesn't have a name (the property does, but not the function), which can be an issue when you're trying to debug because debuggers show you the names of functions in various contexts (call stacks, for instance). If a lot of your functions don't have names, even though the properties referring to them do, it makes debugging difficult. More about anonymous vs. named functions here. (There's also a difference in terms of when the function is instantiated, but going into it here would just complicate things.)

You'd think you could combine things, like this:

this.setOptions = function setOptions() {  // <=== DON'T DO THIS
    ...
};

...but although that mostly works, it triggers a bug in Internet Explorer / JScript (it creates two different functions for that code, which is at best a memory waste and at worst a very subtle and time-wasting problem, as it was in this question).

like image 75
T.J. Crowder Avatar answered Dec 31 '22 02:12

T.J. Crowder