Одним из наиболее распространенных применений упаковщиков функций является сохранение или блокировка в контексте этой функции. Например, если у вас есть какой-то объект и вы хотите использовать один из его методов в качестве обработчика onclick
для данного элемента:
someElement.onclick = someObject.someMethod;
Если someObject.someMethod
делает какие-либо ссылки на this
, вместо this
, указывающего на someObject
, он вместо этого будет указывать на someElement
, поскольку контекст изменился. Заворачивая someObject.someMethod
someElement.onclick = function() { someObject.someMethod() };
вы все еще выполняете someMethod
как метод someObject
, а не как метод someElement
.
Однако, если метод обработчика событий никогда не ссылается на this
, обертка не нужна.
Из примера кода, который вы опубликовали, если вы только что сделали
$(callingImg)[0].setAttribute("onclick", removeChildren(this));
removeChildren(this)
будет выполнено немедленно, и его возвращаемое значение будет назначено как обработчик onclick
.
Вот пример кода, чтобы проиллюстрировать, что происходит
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();
Выход:
h.clickHandler();
`this` = FakeHandlerObject
e.onclick = h.clickHandler;
`this` = FakeElement
e.onclick = function() { h.clickHandler(); };
`this` = FakeHandlerObject
e.onclick = h.clickHandler();
`this` = FakeHandlerObject
Как примечание, похоже, что вы используете jQuery. Если это так, вы можете просто сделать
$($(callingImg)[0]).click(function() {
removeChildren(this);
});
еще лучше, если всегда есть один callingImg
или вы хотите применить один и тот же обработчик щелчков к каждому callingImg
, вы можете просто сделать
$(callingImg).click(function() {
removeChildren(this);
});