「$()。ready(handler)」が推奨されないのはなぜですか?


88

以下からのjQuery APIドキュメントサイトについてready

次の3つの構文はすべて同等です。

  • $(document).ready(handler)
  • $()。ready(handler)(これは推奨されません)
  • $(ハンドラ)

宿題- ソースコードを読んで遊んだ後、なぜなのかわからない

$().ready(handler) 

推奨されません。1番目と3番目の方法はまったく同じです。3番目のオプションは、キャッシュされたjQueryオブジェクトのready関数を次のように呼び出します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オブジェクトで関数を呼び出すことができます。

お気に入り:

  • 通常のセレクター:$('a').ready(handler) デモ
  • ナンセンスセレクター:$('fdhjhjkdafdsjkjriohfjdnfj').ready(handler) デモ
  • 未定義のセレクター:$().ready(handler) デモ

最後に...私の質問に:なぜ$().ready(handler)推奨されないのですか?


60
@ChaosPandion:私には、彼は手の甲のように彼が使う道具を理解しようと努力しているようです。私はそれを無駄な努力と正確に呼ぶことはしません。
ジョン

5
良い質問。誰かが興味を持っている場合、ここにパフォーマンス比較があります...これは(少なくともChromeでは)「非推奨」バージョンが実際に最も速いことを示しています。
James Allardice、2012年

5
より良い質問は、これらがまったく存在する理由であり、静的メソッド($.readyたとえば)であり、最初にjQueryオブジェクトを作成する必要がないことです。
エサイリア2012年

2
@Esailijaは、何よりも優れています。jQuery .ready()が個々の要素に何らかの機能を提供することを計画していない限り、jQueryオブジェクトを作成する理由はありません。

2
@ChaosPandion。あなたはそれを使用することはできません... $.readyすでに内部jQuery関数によって取得されていready:ます。ソースコードを検索してください。
gdoronはモニカをサポートしています

回答:


88

jQuery開発者の1人から公式の回答を得ました。

$().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)を実行します。通常、アプリにはdoc readyブロックが1つしかありません。これは、メンテナンスのようなものではありません。

$(fn)もかなり判読不能だと思います。これはWorks™について知っておくべきことです...


1
理にかなっている、jQueryは後方互換性についてかなり真剣です
Esailija '27

@Esailija:彼らがそれほど深刻だったとしても、$()そもそもの振る舞いを切り替えなかったでしょう(その振る舞いがそうであったように、間抜けでした)。一方、あなたは正しいです。彼らは、変更しようとしたときに示されているように、常に重大な変更を加える傾向があるわけではなく.attr()、数日後にすぐに元に戻しました。これは、彼らの不運な初期(および中年期)の設計決定の一部に彼らを拘束しました。

3
@gdoron +1馬の口からまっすぐに。

2
実際の答えを得るための@gdoron +1。そして、はい、私たちは私たちの認識にかなり近づいています。
VisioN、2012年

" それはあなたが作品を知る必要があるものです ™...」まあそうです$(selector[, context])$(html[, ownerDocument])。実際、動作することを知っていることが問題である場合は、jQuery()代わりに使用することもできます$()。または、なぜjQueryを使用するのですか?
JAB 2013

11

さまざまなオプションがあなたが指摘するのとほとんど同じことをするので、ライブラリライターの帽子をかぶって推測します。

  1. おそらく、jQueryの人々は$()将来の使用のために利用できるようにしたいと思います($().ready推奨されていない場合でも、動作することが文書化されているので疑わしいです。$特別な場合のセマンティクスも汚染します)。

  2. はるかに実用的な理由: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. 上記に関連して:readyjQueryオブジェクトが何をラップしても(ここでは何もラップしなくても)同じように機能する(唯一の?)メソッドであるという意味で、奇抜です。これは他のjQueryメソッドのセマンティクスとの大きな違いであるため、特にこれに依存することはお勧めしません。

    更新: Esailijaのコメントが指摘しているように、エンジニアリングの観点からは、readyこのように機能するため、実際には静的メソッドである必要があります。

アップデート#2:ソースを掘り下げると、1.4ブランチのある時点で$()一致するように変更された$([])よう$(document)ですが、1.3ではのように動作しました。この変更により、上記の正当化が強化されます。


私はこのようなコードを見たことがありませんが、古いイディオムは$(document).ready( function(){ //your code here } );
エサイリヤ

2回目の更新が理解できませんでした。もう少し詳しく説明していただけますか?古いバージョンを検索しましたが、この空のjQueryオブジェクトの問題の違いは見つかりませんでした。
gdoronはモニカをサポートする'25

@gdoron:からselector = selector || documentへの変更を意味しif(!selector) return thisます。
2012年

4

空のオブジェクトを$()返すのは単純なことですが、別のものに適用することはできません。それでも動作しますが、直感的ではないと私は言います。$(document)ready()

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

1
はい、同じ認識がこの答えにあります。したがって、変更はバージョン1.4で行われ、新しい返品ポリシーがリリースされました。
VisioN

準備ができたコールバックをアタッチしているときに誰かがドキュメントのタイトルを変更するのを見たことはありません。jQueryを使わずにバニラjsを使用するだけでそれを行うことができます。答えではないかもしれませんが、それは正当な理由ではありません。
gdoronは、

文書のプロパティやメソッドを連鎖させることはできません$()
Alex K.

2
@AlexK。彼の要点は、現実には誰も実際には連鎖し.readyないということでした。確かに誰かがこれを行う理論的な可能性はありますが、コードがそれを行うのを見たことはありません(これは良い議論ではありませんが、ご存知でしょう:D)。
エサイリア2012年

2
たぶん、この理論的なチャンスの方法が原因で、リリースごとに動作が異なるため、この方法は推奨されません
VisioN

3

おそらくこれは単なるドキュメントのバグであり、修正する必要があります$().ready(handler)。使用することの唯一の欠点は、その読みやすさです。確かに、それ$(handler)は同じように判読できないと主張します。同意します。そのため、私はそれを使用しません

また、ある方法が別の方法よりも速いと主張することもできます。ただし、違いに気付くために、どのくらいの頻度でこのメソッドを単一のページの行で何度呼び出しますか?

最終的には個人の好みに帰着します。$().ready(handler)可読性以外の引数を使用することの欠点はありません。この場合、ドキュメントは紛らわしいと思います。


+1!あなたは絶対に正しかった!あなたは公式のjQuery回答を読むのが大好きです。回答として追加しました。
gdoronはモニカをサポートしています

2

3つに不整合があることを明らかに明らかにするために、さらに、よく使用される4番目のフォームを追加しました。 (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、ハンドラーとドキュメントのバージョンのみが、ドキュメントセレクターを取得するときに使用の何かを返すというjQueryの規則に準拠しており、渡されたフォームでは何かを返す必要があります(これは実行しないと思いますが、 「内部」を表示するには、何かがある)。

好奇心旺盛な方のためのフィドルバージョンを以下に示します。http://jsfiddle.net/az85G/


私はそれが何かを見つけていないことに問題が何を見ることができない、あなたはjQueryのために与えたコンテキストがされるnullので、.find('*').length返す0を。この(明白な)振る舞いで何か悪いことを見つけましたか?
gdoronはモニカをサポートしています

@gdoron-この動作に問題はないので、nullでないセレクターがある場合との違いを指摘したかっただけです-この空のセレクターが「速い」コメントが表示される理由であることに注意してください他の場所では処理するオブジェクトが小さいため、そのインスタンスでは「未定義」ではなくオブジェクトが返されます。私はこの質問が本当に好きで、賛成票を投じました:)
Mark Schultheiss

その理由は、それがより速い理由です。なぜなら、トラクターの最初の「中断」条件は、if(!selector) return this他に何かを与える場合、他に何かが起こっているregexということです...親切な言葉をありがとう... jQueryチームにこれに答えてください(地獄、それは私のライブラリではありません:-))。
gdoronは、

ええ、私はコードベースのこの特定の部分を研究していません。バグを途中で修正するためにコアをハッキングしましたが、その部分は修正していません。jQuery(document).ready(function(){});jQueryの専門知識にはさまざまなレベルがあり、jQueryのイベントハンドラー関数であることが新しい人々に「最も明白」であるため、現時点ではコードベースにフォームを表示することを好みます。
Mark Schultheiss、2012年

0

これは、何よりも読みやすさを重視したものだと思います。

これは表現力がありません

$().ready(handler);

なので

$(document).ready(handler)

おそらく、彼らはある種の慣用的なjQueryを宣伝しようとしているのでしょう。


3
$(document).ready(handler)$(handler)ISが推奨するよりも読みやすくなっています...
gdoronはモニカをサポートしてい
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.