2015-08-20 1 views
0

Если вы определяете функцию внутри анонимной функции, например функцию «обратного вызова», используемую в качестве аргумента. Давайте Array.prototype.forEach, например:Выполняет ли функции внутри функций anononymus («обратные вызовы») переопределенную память в каждом обратном вызове?

['one','two','three'].forEach (function(item) { 
    function showValue(i) { 
    console.log (i); 
    } 
    showValue(item); 
}); 

Будет ли функция showValue быть "переопределены" в 3 раза?

Если записать этот код в этом варианте:

function handleItem(item) { 
    function showValue(i) { 
    console.log (i); 
    } 
    showValue(item); 
} 
['one','two','three'].forEach (handleItem); 

Есть ли разница? по-разному или по-другому.

Что об этом варианте:

var handleItem = (function(item) { 

    function showValue(i) { 
    console.log (i); 
    } 

    return function(item) { 
    showValue(item); 
    } 

})(); 


['one','two','three'].forEach (handleItem); 

который я предполагаю, что это более "правильное" закрытие.
Будет ли это иметь какую-то разницу?

+0

Just do 'function showValue (i) {...}' '[...] .forEach (function handleItem (item) {showValue (item);});' – Bergi

ответ

2

Будет ли функция showValue «переопределена» 3 раза?

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

Есть ли разница? по-разному или по-другому.

Только маленький: у вас все еще будет функция handleItem в памяти после завершения итерации. Что касается showItem, ничего не меняется.

Что относительно этой вариации? Я думаю, это более «правильное» закрытие.

Вы будете иметь handleItem после итерации завершается, и все итерации будут использовать один и тот же showItem, который также будет по-прежнему существовать после итерации завершается. (Сторона примечание: item в var handleItem = (function(item) { вводит в заблуждение, вы не принимаете в item там.)


Как вы думаете, один из вариантов «лучше» так или иначе, чем остальные?

Для меня, учитывая код в вопросе, ответ «ни один из вышеперечисленных». Вместо этого:

['one', 'two', 'three'].forEach(function(i) { 
    console.log(i); 
}); 

Я не думаю, что на самом деле есть общий ответ. Это полностью зависит от того, что делают handleItem и showItem, насколько они сложны, независимо от того, собираетесь ли вы их повторно использовать, нужно ли делать то, что связано с данным вызовом, handleItem (кроме этого меняется) и т. Д. ., и т.д.

+0

, пожалуйста, можете ли вы подробно объяснить свой ответ ??? –

+0

Считаете ли вы, что один из вариантов «лучше» каким-то образом, чем остальные? –

+0

@YuvalA .: Я обновил ответ, чтобы ответить на этот вопрос. –