Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

importance of function wrappers in javascript

Can someone explain to me the importance of using function wrappers (ie: when assigning onclick functionality)? I know I should, but I don't fully understand why...

Example: It's my understanding that this:

$(callingImg)[0].setAttribute("onclick", "function(){removeChildren(this);}");

is better than this:

$(callingImg)[0].setAttribute("onclick", "removeChildren(this)");
like image 872
danwoods Avatar asked Feb 06 '26 06:02

danwoods


2 Answers

One of the most common uses of function wrappers is to maintain or lock in that function's context. For example, if you have some object and you want to use one of it's method's as the onclick handler for a given element:

someElement.onclick = someObject.someMethod;

If someObject.someMethod makes any references to this, instead of this pointing to someObject it will instead point to someElement because the context has changed. By wrapping the someObject.someMethod

someElement.onclick = function() { someObject.someMethod() };

you are still executing someMethod as a method of someObject rather than as a method of someElement.

However, if the event handler method never makes any references to this, then a wrapper isn't needed.

From the example code that you posted, if you just did

$(callingImg)[0].setAttribute("onclick", removeChildren(this));

removeChildren(this) would be executed immediately and it's return value would be assigned as the onclick handler.


Here's some sample code to illustrate what's happening

var FakeElement = function() {
    this.name    = "FakeElement";
    this.onclick = function() {};
};

var FakeEventHandler = function() {
    this.name = "FakeHandlerObject";
    this.clickHandler = function() {
        console.log("`this` = ", this.name);
    };
};

var e = new FakeElement(); 
var h = new FakeEventHandler();

// Normal usage, `this` points to instance of `h`
console.info("h.clickHandler();");
h.clickHandler();

// Context of this is changed to `e` instead of `h`
console.info("e.onclick = h.clickHandler;");
e.onclick = h.clickHandler;
e.onclick();

// Wrapped to maintain proper context of `this` within `h`
console.info("e.onclick = function() { h.clickHandler(); };");
e.onclick = function() { h.clickHandler(); };
e.onclick();

// Executed immediately and returns `null` causing an error in `e.onclick();`
console.info("e.onclick = h.clickHandler();");
e.onclick = h.clickHandler();
e.onclick();

Output:

h.clickHandler();
`this` = FakeHandlerObject

e.onclick = h.clickHandler;
`this` = FakeElement

e.onclick = function() { h.clickHandler(); };
`this` = FakeHandlerObject

e.onclick = h.clickHandler();
`this` = FakeHandlerObject

As a side note, it looks like you're using jQuery. If that's the case, you can simply do

$($(callingImg)[0]).click(function() {
    removeChildren(this);
});

better still, if there is always one callingImg or you want to apply the same click handler to every callingImg, you can just do

$(callingImg).click(function() {
    removeChildren(this);
});
like image 53
Justin Johnson Avatar answered Feb 12 '26 11:02

Justin Johnson


They're generally used to limit variable scope and guaranteeing that you won't pollute your surrounding scope(s).

like image 33
Håvard S Avatar answered Feb 12 '26 11:02

Håvard S



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!