Реализация jQuery.each отличается от native Array.forEach - программирование
Подтвердить что ты не робот

Реализация jQuery.each отличается от native Array.forEach

Кто-нибудь, почему отличная отличная функция jQuery.each разработана иначе, чем (теперь) native Array.forEach? F.ex:

var arr = ['abc','def'];
arr.forEach(function(entry, index) {
    console.log(entry); // abc / def
});

Это абсолютный смысл. Но jQuery решил поместить index в качестве первого аргумента:

$.each(arr, function(index, entry) {
   console.log(entry);
});

Кто-нибудь знает причины этого решения? Я всегда использовал $.each экстенсивно, но он всегда искажал меня, что индекс был первым аргументом, поскольку он редко используется. Я знаю, что jQuery реализовал прямую ссылку через this, но это очень запутанно, если вы это сделаете:

​var arr = ['abc','def'];
$.each(arr, function() {
    console.log(this === 'abc'); // false both times, since this is a String constructor
});​​​​​​​​​​​​​​​​​​​​​​​​​​​​​

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

Или, может быть, он разработан таким образом, потому что он также может использоваться на собственных объектах, чем тогда "имеет смысл" поставить ключ до значения в обратном вызове...?

Sidenote: я знаю, что underscore.js(и, возможно, другие библиотеки) делает это наоборот (больше похоже на нативную функцию).

4b9b3361

Ответ 1

Хорошо, я думаю, нам пришлось бы попросить г-на Ресига объяснить это. Факт в том, что ECMAscript 262 edition 5 не был очень распространен, когда был спроектирован и разработан дизайн jQuery, поэтому это определенно вступает в игру. И так как он был спроектирован так, они не захотели впоследствии его менять и сломать весь существующий код.

Фактически, гораздо более вероятно, что вы хотите получить доступ к элементу с более высоким приоритетом, чем его индекс при циклизации массива. Итак, для меня нет разумного объяснения, почему вы сначала передадите индекс в обратные вызовы.

Будьте уверены, что если бы jQuery был изобретен сегодня, они бы выполнили собственное поведение реализации.

С другой стороны, если он слишком сильно вас задевает, вы можете просто создать ярлык и использовать собственный Array.prototype.forEach для повторного набора ваших завершенных наборов jQuery:

var forEach = Function.prototype.call.bind( Array.prototype.forEach );

forEach( $('div'), function( node ) {
    console.log( node );
});

.. и для стандартных массивов просто пойдите с их собственным прототипом.

Ответ 2

Это действительно упоминалось в последнем jQuery conf; к сожалению, я не помню подробностей, но если вы посмотрите достаточно видео из этого, я думаю, вы можете его найти (я думаю, что это было во время Q & A после лейтмотива, но не цитируйте меня на этом). Во всяком случае, кто-то (я не думаю, что это был сам Ресиг, но еще один старший член сообщества jQuery) в основном сказал: "jQuery имеет некоторые вещи, которые, как мы все знаем, проблематичны (" каждый "является одним из примеров, которые они дали), но есть миллионы сайты, которые теперь полагаются на это проблемное поведение, поэтому мы не можем его изменить сейчас".

Таким образом, по сути, ответ заключается в том, что они приняли плохое решение (Resig - НЕВЕРОЯТНЫЙ программист, но даже он не идеален), и теперь все, кто использует jQuery, должны страдать в течение оставшегося времени, потому что библиотека поддерживает относительно высокую обратная совместимость в новых версиях (и пусть это так, хорошо, что вы не хотите переписывать весь сайт каждый раз при обновлении jQuery).

Также стоит упомянуть, что библиотека Underscore имеет метод each с той же сигнатурой, что и встроенный each. Фактически, версия Underscore фактически использует встроенную версию, если она присутствует, для лучшей производительности, полагаясь только на свою версию, если браузер не поддерживает встроенный each. Поскольку объекты jQuery являются просто массивами, вы можете легко использовать их с помощью _.each, а поскольку у Underscore есть много других функций, отсутствующих в jQuery, это отличная библиотека для дополнения jQuery.

Ответ 3

Ну, я согласен, что имеет смысл иметь key секунду, но вы должны иметь в виду, что $.each может использоваться с объектом или массивом, а в случае объекта вы можете использовать ключи, поскольку они имеют смысл.