2013-07-30 1 views
1

Как это:Почему лучше использовать анонимную функцию вместо ссылки на функцию в качестве параметра?

addEventHandler(document.getElementById('btnAdd'), "click", function() 
    { addNewItem(); }, false); 

вместо:

addEventHandler(document.getElementById('btnAdd'), "click", addNewItem, false); 

Я знаю, что это связанно с яваскриптом переводчика (ов), работающим немного больше. Но как?

+0

В вашем примере нет смысла использовать анонимную функцию. – Jivings

+1

Где вы узнали, что ваш первый пример - лучшая практика? – Ian

+0

Первый полезен, когда вам нужно передать параметр 'addNewItem' из этой текущей области. Вы, очевидно, не можете сделать это со своим вторым примером.Но я бы не назвал это «лучшей» практикой. Еще одна причина, по которой ** не использовать анонимную функцию, - это когда она находится внутри цикла, и вы вызываете 'addEventHandler' таким образом. Вы должны создавать новую функцию на каждой итерации, когда вы можете просто просто ссылаться на «addNewItem», который создается один раз – Ian

ответ

4

Использование имени функции позволяет:

  • короче, более читаемым, линии
  • описательные имена
  • легко повторного использования функции в других местах

Passing анонимную функцию, которая не делает ничего, кроме вызывать одну другую функцию (в соответствии с вашим примером) - это просто раздувание - многословность выражения встроенной функции, все еще имея именованную функцию, это худшее из обоих миров ,

+0

В моем ответе есть преимущества, о которых я указываю. –

+0

+1, но есть один случай, когда нужна функция анона: когда явно требуется * not * передать аргумент 'event' (или аналогичный). – Bergi

2

Использование функции присвоения имен включает в себя:

  • больше кода
  • осквернением глобального пространства
  • менее читаемый код, потому что это не очевидно, что функция не используется в других

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

Но если ваш код точно совпадает с тем, который вы показываете, то анонимная функция не имеет никакого смысла. Что было бы эквивалентно анонимный эквивалент второго кода

addEventHandler(document.getElementById('btnAdd'), "click", function() { 
    // addNewItem implementation 
}, false); 

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

+4

Это не обязательно загрязняет глобальное пространство имен ... Объявление может быть в закрытии. – Jivings

+1

@ Подумайте, тогда вы делаете externa l анонимной функции, чтобы избежать использования анонимной функции в качестве обратного вызова ... Если функция не используется повторно, это действительно бессмысленно. –

+0

@dystroy - Нет. Объявление функций ограничено. Вам не нужно использовать выражение функции для его охвата, поэтому оно не будет анонимным. – Quentin

1

Я собираюсь дать свое мнение и не претендовать на эту рекомендацию. Я всегда использовал ссылки на именованные функции как аргументы вместо этого, и я бы никогда не пропускал анонимные функции обертки, когда мог это избежать. Однако я отказался от этого стандарта. Теперь я передаю ссылки на именованные функции, когда не подозреваю, что на моей функции есть много итераций, и я передаю анонимные функции обертки, когда я подозреваю, что там есть итерация подписи моей функции.

Я буду использовать этот JS Fiddle, чтобы объяснить свой предыдущий стандарт, текущий стандарт и почему я отошел от своего старого стандарта. В целом, я узнал из нескольких ошибок, что передача завернутых анонимных функций может быть более надежной, поскольку вы должны явно указать, какие аргументы вы передаете в свою функцию. Тем не менее, оба шаблона имеют свое место.

var btn = document.getElementById('btn'); 
var btn2 = document.getElementById('btn2'); 

//I previously tended to pass in function name references. However, I recently moved towards 
//passing in anonymous functions because I found that pattern to be a bit more refactor safe. 
//More specifically, it is more refactor safe when you suspect the signature of our function 
//will change. If you never expect the function's signature to change, then I guess you shouldn't 
//need to worry about passing in an anonymous function. 

//Because of the way addEventListener uses addNewItem, addNewItem will always receive one 
//paramter: the event object. Therefore, we are not using addNewItem correct. It expects one 
//argument that is message. Previously, we were calling addNewItem correctly when it looked like 
//addNewItemOld and expected zero arguments. Click "Add message incorrect" to see the incorrect 
//behaviour 
btn.addEventListener("click", addNewItem); 

//Now I often to wrap my function calls in anonymous functions because I know exactly what arguments 
//I'm passing into my function. In this case I am explicitely not passing in a message. Now, we are 
//using the addNewItem function correctly 
btn2.addEventListener("click", function(e) { addNewItem(); }); 

//This function has been refactored. It used to look like addNewItemOld. The way 
//this function's signature has been refactored is particularly interesting. It now 
//has an optional paramter called message. 
function addNewItem(message) { 
    var span =document.createTextNode(message || "Now nodes have a default message"), 
     workspace = document.getElementById("workspace"); 
    workspace.appendChild(span); 
} 

function addNewItemOld() { 
    var span =document.createTextNode("Every node has the same message"), 
     workspace = document.getElementById("workspace"); 
    workspace.appendChild(span); 
} 
Смежные вопросы