Важность обертки функций в JavaScript - PullRequest
2 голосов
/ 19 декабря 2009

Может ли кто-нибудь объяснить мне важность использования функций-оболочек (т. Е. При назначении функции onclick)? Я знаю, что должен, но я не до конца понимаю, почему ...

Пример: Насколько я понимаю, это:

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

лучше, чем это:

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

Ответы [ 7 ]

12 голосов
/ 19 декабря 2009

Одним из наиболее распространенных применений упаковщиков функций является сохранение или блокировка в контексте этой функции. Например, если у вас есть какой-то объект и вы хотите использовать один из его методов в качестве обработчика 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);
});
1 голос
/ 16 ноября 2013

очень простой набор функций-оболочек должен использоваться для изоляции объектной модели документа (DOM) от javascript приложения. Таким образом, вы выполняете много вещей, а именно: 1) вы отделяете свою логику от пользовательского агента, тем самым обеспечивая кросс-совместимость браузера, и 2) вы сохраняете кучу кода в своем проекте. Например, спросите себя, сколько раз вы ссылались на функцию «document.getElementById ()»?

Почему бы не создать функцию следующим образом:

function GE (s) {возвращать document.getElementById (s);}

Теперь во всем вашем JavaScript-коде, включая код, содержащийся в вашем HTML (встроенный), вы меняете ссылку на новую функцию, удаляя кучу кода.

Если W3C меняет точку доступа для функции для функции document.getElementById, все, что вам нужно сделать, это изменить ее в одном месте.

Кроме того, теперь вы можете добавить отслеживание ошибок и количество использований в функцию GE ().

То же самое можно сделать для функции document.createElement ().

функция CE (тег) {вернуть document.createElement (тег);}

Во многих приложениях самый первый шаг должен заключаться в том, чтобы изолировать DOM таким образом, создавая функцию-обертку для каждой используемой функции уровня DOM.

Надеюсь, это поможет.

1 голос
/ 19 декабря 2009
$(callingImg)[0].setAttribute("onclick", "function(){removeChildren(this);}");

Это не имеет смысла. Он гласит: по нажатию, определите функцию и ничего не делайте с ней.

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

Это будет работать за исключением IE. Не никогда не используйте setAttribute в HTML-документе. В setAttribute в IE много ошибок, влияющих на различные атрибуты, включая все обработчики событий. И вообще setAttribute не имеет никаких преимуществ перед более короткими и удобными для чтения свойствами HTML уровня DOM уровня 1.

Также он определяет код из строки, что часто считается плохой практикой. Это медленнее, склонно к проблемам с безопасностью, если вы начнете вставлять переменные в строку, и может сломаться в будущем, если будет реализована практика защиты контента.

Чаще всего вы используете функциональный литерал:

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

Тем не менее, $ выглядит так, как будто вы используете jQuery, и в этом случае вы должны использовать собственные средства обработки событий jQuery:

$(callingImg).click(function() {
    removeChildren(this);
});
1 голос
/ 19 декабря 2009

Как правило, они используются для ограничения переменной области и гарантии того, что вы не будете загрязнять окружающую среду.

0 голосов
/ 19 декабря 2009

В этом случае для использования функций-обёрток используется несколько типов: вы можете делать несколько операторов в одном событии или иметь больший контроль над передаваемым аргументом.

Если у вас нет обязательных аргументов, вы можете просто указать имя вызываемой функции в привязке события. В противном случае вы можете поместить встроенную функцию () {} в это пространство для выполнения. Я не вижу смысла ставить его в виде атрибутов элементов так, как вы это делаете.

ш / JQuery

$( callingImg ).click( aFunctionPointer );
// or if you need arguments
$( callingImg ).click( function( ){ aFunction( someArg ); } );

ж / Prototype

Event.observe( callingImg, 'click', aFunctionPointer );
// or if you need arguments
Event.observe( callingImg, 'click', function( ){ aFunction( someArg ); } );

НЕ смешивать и сочетать эти способы, как это

$( callingImg ).click( aFunction( ) ); // DON'T DO IT

, поскольку он будет выполнять функцию aFunction () и будет использовать любое возвращаемое значение (если, конечно, вы не возвращаете функцию, но я сомневаюсь в этом) в качестве события щелчка.

0 голосов
/ 19 декабря 2009

На самом деле это должно быть

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

и

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

Первый - это анонимная функция, определенная в строке, которая будет вызываться после срабатывания события, второй - строка, которую нужно eval 'редактировать, что медленнее и злее.

0 голосов
/ 19 декабря 2009

Таким образом, вы можете повторно использовать функции.

Может быть, объясните чуть более подробно, почему вам неясно, я был бы рад помочь объяснить.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...