Mengapa “$ (). Ready (handler)” tidak disarankan?

88

Dari situs dokumen jQuery API untukready

Ketiga sintaks berikut ini setara:

  • $ (document) .ready (handler)
  • $ (). ready (handler) (ini tidak disarankan)
  • $ (penangan)

Setelah mengerjakan pekerjaan rumah - membaca dan bermain-main dengan kode sumber , saya tidak tahu mengapa

$().ready(handler) 

tidak disarankan. Cara pertama dan ketiga, persis sama, opsi ketiga memanggil fungsi siap pada objek jQuery yang di-cache dengan document:

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

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

Tetapi fungsi siap tidak memiliki interaksi dengan pemilih elemen node yang dipilih, readyKode sumber:

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

Seperti yang Anda lihat, itu hanya menambahkan callback ke antrian internal ( readyList) dan tidak mengubah atau menggunakan elemen dalam set. Ini memungkinkan Anda memanggil readyfungsi pada setiap objek jQuery.

Suka:

  • pemilih reguler : $('a').ready(handler) DEMO
  • Pemilih yang tidak masuk akal : $('fdhjhjkdafdsjkjriohfjdnfj').ready(handler) DEMO
  • Pemilih tidak ditentukan : $().ready(handler) DEMO

Akhirnya ... untuk pertanyaan saya: Mengapa $().ready(handler)tidak direkomendasikan?

gdoron mendukung Monica
sumber
60
@ChaosPandion: Bagi saya sepertinya dia berusaha untuk memahami alat yang dia gunakan seperti punggung tangannya. Saya tidak akan menyebut upaya itu sia-sia.
Jon
5
Pertanyaan bagus. Jika ada yang tertarik, berikut ini perbandingan kinerja ... yang menunjukkan (setidaknya di Chrome) bahwa versi "tidak disarankan" sebenarnya adalah yang tercepat.
James Allardice
5
Pertanyaan yang lebih baik adalah mengapa ini bahkan ada, itu harus menjadi metode statis ( $.readymisalnya) dan tidak perlu membangun objek jQuery di tempat pertama.
Esailija
2
@Esailija membuat poin terbaik dari semuanya. Kecuali jika jQuery berencana menyediakan semacam .ready()kemampuan untuk elemen individual, seharusnya tidak ada alasan untuk membuat objek jQuery.
2
@Septianjoko_ Anda tidak dapat menggunakan itu ... $.readysudah diambil oleh fungsi jQuery internal, cari kode sumbernya ready:.
gdoron mendukung Monica

Jawaban:

88

Saya mendapat jawaban resmi dari salah satu pengembang jQuery:

$().ready(fn)hanya berfungsi karena $()dulunya adalah pintasan ke $(document) (jQuery <1.4)
Jadi $().ready(fn)kode yang dapat dibaca.

Tapi orang biasa melakukan hal-hal seperti $().mouseover()dan segala macam kegilaan lainnya.
dan yang harus dilakukan orang $([])untuk mendapatkan objek jQuery kosong

Jadi di 1.4 kami mengubahnya jadi $()memberikan jQuery kosong dan kami baru saja membuat $().ready(fn)pekerjaan agar tidak merusak banyak kode

$().ready(fn) secara harfiah sekarang hanya ditambal di inti agar berfungsi dengan baik untuk kasus lama.

Tempat terbaik untuk readyfungsinya adalah $.ready(fn), tetapi ini adalah keputusan desain yang sangat lama dan itulah yang kita miliki sekarang.


Saya bertanya kepadanya:

Apakah menurut Anda $ (fn) lebih mudah dibaca daripada $ (). Ready (fn)?!

Jawabannya adalah:

Saya selalu melakukan $ (document) .ready (fn) di aplikasi aktual dan biasanya hanya ada satu blok siap dokumen di aplikasi itu tidak persis seperti pemeliharaan.

Saya pikir $ (fn) juga cukup tidak terbaca , itu hanya A Thing That You Have To Know Works ™ ...

gdoron mendukung Monica
sumber
1
Masuk akal, jQuery cukup serius tentang
kompatibilitas
@ Esailija: Jika mereka seserius itu, mereka tidak akan mengubah perilakunya $()sejak awal (sama konyolnya dengan perilaku itu) . Di sisi lain, Anda benar. Mereka tidak selalu cenderung membuat perubahan yang melanggar, seperti yang ditunjukkan saat mereka mencoba mengubah .attr(), lalu melakukan perubahan cepat beberapa hari kemudian. Ini telah mengikat mereka pada beberapa keputusan desain awal (dan paruh baya) yang tidak menguntungkan.
3
@gdoron +1 untuk mendapatkannya langsung dari mulut kuda.
2
@gdoron +1 untuk mendapatkan jawaban yang sebenarnya. Dan, ya, persepsi kita sudah cukup dekat.
VisioN
" Itu hanya Hal yang Harus Anda Ketahui Bekerja ™ ..." Begitu juga $(selector[, context])dan $(html[, ownerDocument]). Faktanya, Anda mungkin juga hanya menggunakan jQuery()daripada $()jika harus tahu-itu-masalahnya adalah masalahnya. Atau mengapa bahkan menggunakan jQuery sama sekali?
JAB
11

Karena opsi yang berbeda melakukan hal yang hampir sama seperti yang Anda tunjukkan, inilah saatnya untuk mengenakan topi penulis perpustakaan dan membuat beberapa tebakan.

  1. Mungkin orang-orang jQuery ingin $()tersedia untuk digunakan di masa mendatang (diragukan karena $().readydidokumentasikan untuk bekerja, bahkan jika tidak direkomendasikan; itu juga akan mencemari semantik $jika kasus khusus).

  2. Alasan yang jauh lebih praktis: versi kedua adalah satu-satunya yang tidak berakhir dengan penggabungan document, jadi lebih mudah untuk dipecahkan saat mempertahankan kode. Contoh:

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

    Bandingkan ini dengan

    // BEFORE
    $().ready(foo);
    
    // AFTER: breaks
    $().ready(foo).on("click", "a", function() {});
    
  3. Terkait dengan hal di atas: readyadalah freak dalam arti bahwa itu (satu-satunya?) Metode yang akan bekerja sama tidak peduli apa yang dibungkus objek jQuery (bahkan jika itu tidak membungkus apa pun seperti yang terjadi di sini). Ini adalah perbedaan utama dari semantik metode jQuery lainnya, jadi secara khusus mengandalkan ini tidak disarankan.

    Pembaruan: Seperti yang ditunjukkan oleh komentar Esailija, dari perspektif teknik readyharus benar-benar menjadi metode statis karena cara kerjanya seperti ini.

Pembaruan # 2: Menggali sumbernya, tampaknya di beberapa titik di cabang 1.4 $()diubah agar sesuai $([]), sementara di 1.3 berperilaku seperti itu $(document). Perubahan ini akan memperkuat justifikasi di atas.

Jon
sumber
Saya belum pernah melihat kode seperti ini, ungkapan lama adalah$(document).ready( function(){ //your code here } );
Esailija
Saya tidak dapat memahami pembaruan kedua, bisakah Anda menjelaskan lebih lanjut? Saya mencari versi yang lebih lama, tetapi tidak dapat menemukan perbedaan apa pun untuk masalah objek jQuery kosong ini.
gdoron mendukung Monica
@gdoron: Maksud saya perubahan dari selector = selector || documentmenjadi if(!selector) return this.
Jon
4

Saya akan mengatakan itu hanya fakta yang $()mengembalikan objek kosong sedangkan $(document)tidak begitu Anda menerapkan ready()ke hal-hal yang berbeda; itu masih berfungsi, tetapi saya akan mengatakan itu tidak intuitif.

$(document).ready(function(){}).prop("title") // the title
$().ready(function(){}).prop("title")  //null - no backing document
Alex K.
sumber
1
Ya, persepsi yang sama ada dalam jawaban ini . Jadi perubahan terjadi pada versi 1.4, yang merilis kebijakan pengembalian baru.
VisioN
Saya belum pernah melihat seseorang mengubah judul dokumen sambil melampirkan callback siap, Dan Anda cukup melakukannya dengan vanilla js tanpa jQuery . Saya tidak mengatakan itu mungkin bukan jawabannya, tapi itu bukan alasan yang bagus.
gdoron mendukung Monica
Tidak ada properti atau metode dokumen yang dapat dirantai melalui$()
Alex K.
2
@Lukmania intinya adalah bahwa tidak ada orang dalam kenyataan yang benar-benar mengikat .readykarena itu adalah ungkapan yang mapan untuk tidak melakukannya. Tentu ada kemungkinan teoritis seseorang melakukan ini tetapi saya belum pernah melihat kode melakukan itu (yang bukan argumen yang bagus tetapi Anda tahu: D).
Esailija
2
Mungkin karena metode kebetulan teoritis ini tidak disarankan , karena memiliki perilaku yang berbeda dalam rilis yang berbeda.
VisioN
3

Kemungkinan besar ini hanya bug dokumentasi dan harus diperbaiki, satu-satunya downside untuk menggunakan $().ready(handler)adalah keterbacaannya. Tentu, membantah itu $(handler)sama tidak terbacanya. Saya setuju, itulah mengapa saya tidak menggunakannya .

Anda juga dapat berargumen bahwa satu metode lebih cepat dari yang lain. Namun, seberapa sering Anda memanggil metode ini cukup sering berturut-turut pada satu halaman untuk melihat perbedaannya?

Pada akhirnya itu tergantung pada preferensi pribadi. Tidak ada kerugian untuk menggunakan $().ready(handler)selain argumen keterbacaan. Saya pikir dokumentasinya salah memimpin dalam kasus ini.

Kevin B
sumber
+1! Anda memang benar! Anda akan senang membaca jawaban jQuery resmi. Saya menambahkannya sebagai jawaban.
gdoron mendukung Monica
2

Hanya untuk memperjelas bahwa ada beberapa ketidakkonsistenan dalam ketiganya, ditambah saya menambahkan formulir keempat yang sering digunakan: (function($) {}(jQuery));

Dengan markup ini:

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

dan kode ini:

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);
});

Hasil div yang ditampilkan dari pernyataan terakhir adalah: 0: 9: 9: 9: tidak terdefinisi

JADI, hanya versi Handler dan Doc yang konsisten dengan konvensi jQuery untuk mengembalikan sesuatu yang berguna karena mereka mendapatkan pemilih dokumen dan dengan formulir Lulus Anda harus mengembalikan sesuatu (saya tidak akan melakukan ini, saya pikir, tetapi taruh di dalamnya saja untuk menunjukkan "di dalam" itu memiliki sesuatu).

Berikut adalah versi biola ini untuk yang penasaran: http://jsfiddle.net/az85G/

Mark Schultheiss
sumber
Aku tidak bisa melihat apa masalahnya dengan itu itu tidak menemukan apa-apa, konteks yang Anda berikan untuk jQuery nullsehingga .find('*').lengthkembali 0 . Apakah Anda menemukan sesuatu yang buruk dengan perilaku (jelas) ini?
gdoron mendukung Monica
@gdoron - Saya tidak menemukan sesuatu yang buruk dengan perilaku ini, saya hanya ingin menunjukkan perbedaannya dibandingkan ketika TIDAK memiliki pemilih yang TIDAK null - perhatikan bahwa pemilih kosong ini kemungkinan menjadi alasan mengapa komentar "lebih cepat" dicatat di tempat lain karena memiliki objek yang lebih kecil untuk diproses, tetapi TIDAK mengembalikan objek dan tidak "tidak ditentukan" dalam contoh itu. Saya benar-benar menyukai pertanyaan itu dan melakukan upvote itu :)
Mark Schultheiss
Alasan mengapa lebih cepat adalah, karena kondisi "istirahat" pertama dari ctor adalah if(!selector) return thisjika Anda memberikan sesuatu yang lain, ada regexdan hal-hal lain terjadi ... Terima kasih atas kata-kata yang baik ... Saya rasa saya mungkin akan meminta tim jQuery untuk jawab ini (sih, ini bukan perpustakaanku :-)).
gdoron mendukung Monica
Ya, saya belum mempelajari bagian khusus dari basis kode ini, saya telah meretas inti untuk memasang perbaikan interum untuk bug tetapi bukan bagian itu. Saya lebih suka melihat jQuery(document).ready(function(){});formulir dalam basis kode kami saat ini karena ada tingkat keahlian jQuery yang berbeda dan "paling jelas" bagi orang baru bahwa itu IS fungsi penanganan acara untuk jQuery.
Mark Schultheiss
0

Saya pikir ini benar-benar lebih untuk keterbacaan daripada apa pun.

Yang ini tidak terlalu ekspresif

$().ready(handler);

sebagai

$(document).ready(handler)

Mungkin mereka mencoba mempromosikan beberapa bentuk jQuery idiomatik.

Hyangelo
sumber
3
$(document).ready(handler)lebih mudah dibaca daripada $(handler)yang direkomendasikan IS ...
gdoron mendukung Monica