Причина.)($" готов(обработчик)" не рекомендуется?


С jQuery API docs site на ready

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

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

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

$().ready(handler) 

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

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

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

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

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

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

как:

  • обычный селектор: $('a').ready(handler)демо
  • ерунда селектор: $('fdhjhjkdafdsjkjriohfjdnfj').ready(handler)демо
  • Undefined селектор:$().ready(handler)демо

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

6 88

6 ответов:

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

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

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

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

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

лучшее место для

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

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

  2. гораздо более практическая причина: вторая версия единственный, кто делает не в конечном итоге упаковка 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() {});
    
  3. связанные с вышеизложенным:ready урод в том смысле, что он (единственный?) метод, который будет работать одинаково независимо от того, что обертывает объект jQuery (даже если он ничего не обертывает, как в данном случае). Это существенное отличие от семантики других jQuery методы, поэтому специально полагаться на это справедливо не рекомендуется.

    обновление: как отмечает комментарий Эсаилия, с инженерной точки зрения ready должен быть статический метод именно потому, что это работает так.

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

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

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

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

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

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

просто чтобы было очевидно, что есть некоторая несогласованность в трех, плюс я добавил четвертую часто используемую форму:(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

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

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

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

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

$().ready(handler);

как

$(document).ready(handler)

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