Вопрос по callback, document-ready, javascript, jquery – Почему «$ (). Ready (обработчик)» не рекомендуется?

88

ОтСайт документации jQuery API заready

All three of the following syntaxes are equivalent:

$(document).ready(handler) $().ready(handler) (this is not recommended) $(handler)

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

$().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 исходный код:

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

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

Подобно:

regular selector: $('a').ready(handler) DEMO Nonsense selector: $('fdhjhjkdafdsjkjriohfjdnfj').ready(handler) DEMO Undefined selector:$().ready(handler) DEMO

Наконец-то ... на мой вопрос:Why $().ready(handler) is not recommended?

Лучший вопрос: почему они вообще существуют, это должен быть статический метод ($.ready например) и не требует создания объекта jQuery в первую очередь. Esailija
@Esailija делает лучшее из всех. Если только jQuery не планирует предоставлять какие-либо.ready() возможность для отдельных элементов, не должно быть никаких оснований для создания объекта jQuery. user1106925
Хороший вопрос. Если кому-то интересно,here is a performance comparison... который показывает (по крайней мере в Chrome), что "не рекомендуется" версия на самом деле самая быстрая. James Allardice
@ChaosPandion. Вы не можете использовать это ...$.ready уже занята внутренней функцией jQuery, ищите в исходном кодеready:. gdoron
@ChaosPandion: Мне кажется, что он стремится понять инструменты, которые он использует, как тыльную сторону ладони. Я бы точно не назвал это потраченным впустую усилием. Jon

Ваш Ответ

6   ответов
3

это всего лишь ошибка документации, и ее следует исправить, единственный недостаток в использовании$().ready(handler) это удобочитаемость. Конечно, утверждаю, что$(handler) так же нечитабельно Согласен,that's why I don't use it.

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

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

+1! Вы были абсолютно правы! Вам понравится читать официальный ответ JQuery. Я добавил это как ответ. gdoron
4

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

$(document).ready(function(){}).prop("title") // the title
$().ready(function(){}).prop("title")  //null - no backing document
@AlexK. он имел в виду, что на самом деле никто на самом деле не цепляет после.ready потому что это устоявшаяся идиома не делать. Конечно, есть теоретический шанс, что кто-то сделает это, но я никогда не видел, чтобы код делал это (что не является хорошим аргументом, но вы знаете: D).
Ну, никакие свойства или методы документа не могут быть связаны через$()
Да, то же самое восприятие вthis answer, Таким образом, изменения произошли в версии 1.4, которая выпустила новую политику возврата.
Может из-за этогоtheoretical chance методnot recommended, поскольку он имеет разное поведение в разных выпусках.
Я никогда не видел, чтобы кто-то изменял заголовок документа при прикреплении готового обратного вызова, иyou can simply do it with vanilla js without jQuery, Я не говорю, что это не может быть ответом, но это не веская причина. gdoron
11

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

Perhaps the jQuery people would like to have $() available for future use (doubtful since $().ready is documented to work, even if not recommended; it would also pollute the semantics of $ if special-cased).

A much more practical reason: the second version is the only one that does not end up wrapping document, so it's easier to break when maintaining the code. Example:

// BEFORE
$(document).ready(foo);

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

Contrast this with

// BEFORE
$().ready(foo);

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

Related to the above: ready is a freak in the sense that it's (the only?) method that will work the same no matter what the jQuery object wraps (even if it does not wrap anything as is the case here). This is a major difference from the semantics of other jQuery methods, so specifically relying on this is rightly discouraged.

Update: As Esailija's comment points out, from an engineering perspective ready should really be a static method exactly because it works like this.

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

@gdoron: я имею в виду изменение отselector = selector || document вif(!selector) return this.
Я никогда не видел такой код, хотя старая идиома$(document).ready( function(){ //your code here } );
Я не могу понять второе обновление, не могли бы вы рассказать подробнее? Я искал более старые версии, но не смог найти никакой разницы для этой пустой проблемы с объектом jQuery. gdoron
0

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

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

$().ready(handler);

как

$(document).ready(handler)

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

$(document).ready(handler) более читабельно, чем$(handler) который рекомендуется ... gdoron
2

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

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

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

@ gdoron - я не нахожу ничего плохого в этом поведении, я просто хотел бы указать на разницу по сравнению с тем, когда он имеет селектор, который НЕ является нулевым, - обратите внимание, что этот пустой селектор, вероятно, почему "быстрее" комментарии отмечены в другом месте, так как он имеет меньший объект для обработки, но возвращает объект, а не & quot; неопределенный & quot; в этом случае. Мне действительно нравится этот вопрос, и я его высказал :)
Я не вижу, в чем проблема с тем, что он ничего не находит, контекст, который вы задали для jQuery,null так.find('*').length вернуть0, Вы находите что-то плохое в этом (очевидном) поведении? gdoron
Причина состоит в том, почему это происходит быстрее, потому что первый «перерыв» состояние ctorif(!selector) return this если вы дадите что-то еще, естьregex и другие вещи ... Спасибо за добрые слова ... Я думаю, я мог бы попросить команду jQuery ответить на этот вопрос (черт возьми, это не моя библиотека:-)). gdoron
Да, я не изучал эту конкретную часть базы кода, я взломал ядро, чтобы внести промежуточные исправления для ошибок, но не эту его часть. Я предпочитаю видетьjQuery(document).ready(function(){}); формы в нашей кодовой базе в настоящее время, поскольку существуют различные уровни экспертизы jQuery, и это "наиболее очевидно" для новых людей, что это функция обработчика событий для jQuery.
87

I got an official answer from one of the jQuery developers:

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

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

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

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

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

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

Do you think that $(fn) is more readable than $().ready(fn) ?!

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

I always do $(document).ready(fn) in actual apps and typically there's only one doc ready block in the app it's not exactly like a maintenance thing.

I think $(fn) is pretty unreadable too, it's just A Thing That You Have To Know Works™...

@gdoron +1 за то, что получил прямо изо рта лошади.
Имеет смысл, jQuery довольно серьезно относится к обратной совместимости
@Esailija: Если бы они были настолько серьезны, они бы не изменили поведение$() на первом месте(as goofy as that behavior may have been), С другой стороны, вы правы. Они не всегда так склонны вносить серьезные изменения, как это было показано, когда они пытались изменить.attr(), а затем сделал быстрый возврат через несколько дней. Это связало их с некоторыми из их неудачных ранних (и средних лет) дизайнерских решений.
& Quot;it's just A Thing That You Have To Know Works & # X2122; ... & Quot; Ну так и есть$(selector[, context]) а также$(html[, ownerDocument]), На самом деле, вы могли бы просто использоватьjQuery() вместо$() если проблема заключается в том, чтобы знать, как это работает. Или зачем вообще использовать jQuery?
@gdoron +1 для получения реального ответа. И да, мы были достаточно близки в нашем восприятии.

Похожие вопросы