Почему "$(). Ready (handler)" не рекомендуется?

На сайте docs jQuery API для ready

Все три следующих синтаксиса эквивалентны:

  • $(документ).ready(обработчик)
  • $(). ready (обработчик) (это не рекомендуется)
  • $(обработчик)

После выполнения домашней работы - чтения и воспроизведения с исходным кодом, я понятия не имею, почему

$().ready(handler) 

не рекомендуется. Первый и третий способы, точно такие же, третий вариант вызывает готовую функцию к кешированному объекту jQuery с помощью document:

rootjQuery = jQuery(document);
...
...

// HANDLE: $(function)
// Shortcut for document ready
} else if ( jQuery.isFunction( selector ) ) {
    return rootjQuery.ready( selector );
}

Но функция ready не имеет никакого взаимодействия с селектором выбранных элементов node, исходный код ready:

ready: function( fn ) {
    // Attach the listeners
    jQuery.bindReady();
        // Add the callback
    readyList.add( fn );
        return this;
},

Как вы можете видеть, он просто добавляет обратный вызов во внутреннюю очередь (readyList) и не меняет или не использует элементы в наборе. Это позволяет вам вызвать функцию ready для каждого объекта jQuery.

Как

  • регулярный селектор: $('a').ready(handler) DEMO
  • Сериал ерунда: $('fdhjhjkdafdsjkjriohfjdnfj').ready(handler) DEMO
  • Undefined: $().ready(handler) DEMO

Наконец... на мой вопрос: Почему $().ready(handler) не рекомендуется?

Ответ 1

Я получил официальный ответ от одного из разработчиков jQuery:

$().ready(fn) работает только потому, что $() был ярлыком для $(document) (jQuery < 1.4)
Таким образом, $().ready(fn) был читаемым кодом.

Но люди обычно делали такие вещи, как $().mouseover() и всевозможные другие безумие.
и люди должны были сделать $([]), чтобы получить пустой объект jQuery

Итак, в 1.4 мы изменили его, поэтому $() дает пустой jQuery, и мы просто сделали $().ready(fn) работу, чтобы не сломать много кода

$().ready(fn) буквально теперь просто исправлен в ядре, чтобы он работал правильно для устаревшего случая.

Лучшим местом для функции ready является $.ready(fn), но это действительно старое дизайнерское решение, и именно это мы имеем сейчас.


Я спросил его:

Считаете ли вы, что $(fn) более читабельно, чем $(). ready (fn)?!

Его ответ был:

Я всегда делаю $(document).ready(fn) в реальных приложениях и, как правило, в приложении только один готовый блок документа, он не совсем похож на предмет обслуживания.

Я думаю, что $(fn) тоже довольно нечитабельно, это просто A Thing That You To To Know Works ™...

Ответ 2

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

  • Возможно, люди jQuery хотели бы иметь $() для будущего использования (сомнительно, поскольку $().ready документируется для работы, даже если это не рекомендуется, а также будет загрязнять семантику $ обсаженный).

  • Гораздо более практичная причина: вторая версия - единственная, которая не заканчивается оберткой document, поэтому ее легче разбить при обслуживании кода. Пример:

    // BEFORE
    $(document).ready(foo);
    
    // AFTER: works
    $(document).ready(foo).on("click", "a", function() {});
    

    Контрастируйте это с помощью

    // BEFORE
    $().ready(foo);
    
    // AFTER: breaks
    $().ready(foo).on("click", "a", function() {});
    
  • Связано с вышесказанным: ready является уродцем в том смысле, что он (единственный?) метод будет работать одинаково независимо от того, что объект jQuery обертывает (даже если он не обертывает ничего, как случай здесь). Это существенное отличие от семантики других методов jQuery, поэтому, в частности, это оправдано.

    Обновление: Как отмечает Esailija, с технической точки зрения ready действительно должен быть статическим методом, так как он работает следующим образом.

Обновление # 2:. Копаясь в источнике, кажется, что в какой-то момент в ветке 1.4 $() было изменено на соответствие $([]), а в 1.3 оно вел себя как $(document). Это изменение укрепит приведенные выше обоснования.

Ответ 3

Я бы сказал, что это просто факт, что $() возвращает пустой объект, тогда как $(document) не делает ваше применение ready() для разных вещей; он все еще работает, но я бы сказал, что он не интуитивно понятен.

$(document).ready(function(){}).prop("title") // the title
$().ready(function(){}).prop("title")  //null - no backing document

Ответ 4

Скорее всего, это просто ошибка с документацией и должна быть исправлена, единственной минутой использования $().ready(handler) является ее читаемость. Конечно, утверждают, что $(handler) так же нечитабельно. Я согласен, почему я не использую его.

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

В конечном счете это сводится к личным предпочтениям. Нет недостатка в использовании $().ready(handler), кроме аргумента читаемости. Я думаю, что в этом случае документация не работает.

Ответ 5

Просто, чтобы сделать это явно очевидным, что в трех случаях есть некоторая несогласованность, плюс я добавил четвертую часто используемую форму: (function($) {}(jQuery));

С этой разметкой:

<div >one</div>
<div>two</div>
<div id='t'/>

и этот код:

var howmanyEmpty = $().ready().find('*').length;
var howmanyHandler = $(function() {}).find('*').length;
var howmanyDoc = $(document).ready().find('*').length;
var howmanyPassed = (function($) { return $('*').length; }(jQuery));
var howmanyYuck = (function($) {}(jQuery));
var howmanyYuckType = (typeof howmanyYuck);

$(document).ready(function() {
    $('#t').text(howmanyEmpty + ":" + howmanyHandler + ":" 
        + howmanyDoc + ":" + howmanyPassed + ":" + howmanyYuckType);
});

Отображаемые результаты div из последнего оператора: 0: 9: 9: 9: undefined

SO, только версии Handler и Doc согласуются с соглашением jQuery о возврате чего-то полезного, поскольку они получают селектор документов, а с переданной формой вы должны что-то возвращать (я бы не сделал этого, я бы подумал, но поставил это просто для того, чтобы показать "внутри" что-то есть).

Вот версия скрипта для любопытных: http://jsfiddle.net/az85G/

Ответ 6

Я думаю, что это действительно больше для читаемости, чем что-либо еще.

Это не так выразительно

$().ready(handler);

а

$(document).ready(handler)

Возможно, они пытаются продвинуть какую-то форму идиоматического jQuery.