क्यों "$ () तैयार है (हैंडलर)" अनुशंसित नहीं है?


88

के लिए jQuery एपीआई डॉक्स साइट सेready

निम्नलिखित तीनों वाक्यविन्यास समतुल्य हैं:

  • $ (Document) .ready (हैंडलर)
  • $ () तैयार है (हैंडलर) (यह अनुशंसित नहीं है)
  • $ (हैंडलर)

होमवर्क करने के बाद - सोर्स कोड के साथ पढ़ना और खेलना , मुझे पता नहीं क्यों

$().ready(handler) 

अनुशंसित नहीं है। पहले और तीसरे तरीके, बिल्कुल समान हैं, तीसरा विकल्प तैयार फ़ंक्शन को कैश्ड 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) DEMO
  • बकवास चयनकर्ता: $('fdhjhjkdafdsjkjriohfjdnfj').ready(handler) DEMO
  • अनिर्धारित चयनकर्ता: $().ready(handler) DEMO

अंत में ... मेरे प्रश्न के लिए: क्यों $().ready(handler)अनुशंसित नहीं है?


60
@ChaosPandion: मेरे लिए ऐसा लगता है कि वह अपने हाथ के पीछे की तरह उपयोग किए जाने वाले उपकरणों को समझने का प्रयास करता है। मैं बिल्कुल उस व्यर्थ प्रयास को नहीं कहूंगा।
जॉन

5
अच्छा प्रश्न। अगर किसी को दिलचस्पी है, तो यहां एक प्रदर्शन तुलना है ... जो दिखाता है (क्रोम में कम से कम) कि "अप्रतिबंधित" संस्करण वास्तव में सबसे तेज है।
जेम्स एलार्डिस

5
एक बेहतर सवाल यह है कि ये सब क्यों मौजूद हैं, यह एक स्थिर विधि होना चाहिए ( $.readyउदाहरण के लिए) और पहली जगह में एक jQuery ऑब्जेक्ट के निर्माण की आवश्यकता नहीं है।
एस्लेइजा

2
@Esailija सभी का सबसे अच्छा बिंदु बनाता है। जब तक .ready()व्यक्तिगत तत्वों के लिए किसी प्रकार की क्षमता प्रदान करने के लिए jQuery की योजना नहीं है, तब तक jQuery ऑब्जेक्ट के निर्माण का कोई कारण नहीं होना चाहिए।

2
@ChaosPandion। आप इसका उपयोग नहीं कर सकते ... $.readyपहले से ही एक आंतरिक jQuery फ़ंक्शन द्वारा लिया गया है, के लिए स्रोत कोड खोजें ready:
गदोरन

जवाबों:


88

मुझे jQuery डेवलपर्स में से एक से एक आधिकारिक उत्तर मिला:

$().ready(fn)केवल इसलिए काम करता है क्योंकि $()इसका शॉर्टकट $(document) (jQuery <1.4) हुआ करता था,
इसलिए $().ready(fn)यह एक पठनीय कोड था।

लेकिन लोग $().mouseover()अन्य सभी तरह के पागलपन की तरह काम करते थे ।
और लोगों को $([])एक खाली jQuery ऑब्जेक्ट प्राप्त करने के लिए करना था

इसलिए 1.4 में हमने इसे बदल दिया इसलिए $()यह एक खाली jQuery देता है और हमने $().ready(fn)बहुत सारे कोड को नहीं तोड़ने के लिए काम किया है

$().ready(fn) वस्तुतः अब यह विरासत के मामले में ठीक से काम करने के लिए सिर्फ कोर में पैच किया गया है।

readyफ़ंक्शन के लिए सबसे अच्छी जगह है $.ready(fn), लेकिन यह वास्तव में एक पुराना डिजाइन निर्णय है और यही अब हमारे पास है।


मैंने उससे पूछा:

क्या आपको लगता है कि $ (fn) $ ()। रेडी (fn) से अधिक पठनीय है?!

उनका जवाब था:

मैं हमेशा वास्तविक ऐप्स में $ (डॉक्यूमेंट) पहले से ही (fn) करता हूं और आमतौर पर ऐप में केवल एक डॉक रेडी ब्लॉक होता है, यह बिल्कुल मेंटेनेंस की तरह नहीं है।

मुझे लगता है कि $ (fn) बहुत अपठनीय है , यह सिर्फ एक बात है जो आपको काम करना है ...


1
समझ में आता है, jQuery बैकवर्ड
कम्पैटिबिलिटी के

@Esailija: यदि वे उस गंभीर थे, तो उन्होंने $()पहली जगह के व्यवहार को बदल नहीं दिया होगा (जैसा कि उस व्यवहार के अनुसार नासमझ हो सकता है) । दूसरी ओर, आप सही कह रहे हैं। वे हमेशा परिवर्तन को बदलने के लिए इच्छुक नहीं होते हैं, जैसा कि दिखाया गया था जब उन्होंने बदलने की कोशिश की .attr()थी, फिर कुछ दिनों बाद एक त्वरित वापसी की। इसने उन्हें अपने कुछ दुर्भाग्यपूर्ण शुरुआती (और मिडलाइफ़) डिज़ाइन निर्णयों के लिए बाध्य किया है।

3
@gdoron +1 घोड़े के मुंह से सीधा होने के लिए।

2
असली जवाब पाने के लिए @gdoron +1। और, हां, हम अपनी धारणाओं में काफी निकट हैं।
VisioN

" यह सिर्फ एक बात है कि आपको काम करने के लिए पता है ™ ..." ठीक है, इसलिए $(selector[, context])और हैं $(html[, ownerDocument])। वास्तव में, हो सकता है कि आप यह जानने के jQuery()बजाय $()कि यह काम करता है, केवल इसका उपयोग करें । या यहाँ तक कि jQuery का उपयोग क्यों करें?
JAB

11

चूंकि अलग-अलग विकल्प बहुत अधिक समान काम करते हैं जैसा कि आप बताते हैं, यह पुस्तकालय लेखक की टोपी लगाने और कुछ अनुमान लगाने का समय है।

  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 शाखा $()में मिलान करने के लिए बदल दिया गया था $([]), जबकि 1.3 में ऐसा व्यवहार किया गया था $(document)। यह परिवर्तन उपरोक्त औचित्य को सुदृढ़ करेगा।


मैंने इस तरह का कोड कभी नहीं देखा है, पुराना मुहावरा था$(document).ready( function(){ //your code here } );
एस्लेइजा

मैं दूसरा अपडेट नहीं समझ सका, क्या आप कृपया कुछ और विस्तृत कर सकते हैं? मैंने पुराने संस्करणों की खोज की, लेकिन इस खाली jQuery ऑब्जेक्ट समस्या के लिए कोई अंतर नहीं पाया।
गॉर्डन मोनिका का

@gdoron: मैं से परिवर्तन करना पड़ता selector = selector || documentकरने के लिए if(!selector) return this
जॉन

4

मैं इसके साधारण रूप से कहना चाहूंगा कि $()एक खाली वस्तु लौटाता है जबकि विभिन्न चीजों पर $(document)आपका आवेदन नहीं करता है ready(); यह अभी भी काम करता है, लेकिन मैं कहूंगा कि यह सहज नहीं है।

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

1
हां, इस जवाब में वही धारणाएं हैं । इसलिए बदलाव 1.4 संस्करण में हुए, जिसने नई वापसी नीति जारी की।
VisioN

मैंने किसी को तैयार कॉलबैक को संलग्न करते हुए दस्तावेज़ का शीर्षक बदलते हुए कभी नहीं देखा है, और आप बस इसे jQuery के बिना वेनिला जेएस के साथ कर सकते हैं । मैं नहीं कहता कि यह उत्तर नहीं हो सकता है, लेकिन यह एक अच्छा कारण नहीं है।
गदोरन

अच्छी तरह से कोई दस्तावेज़ गुण या विधियों के माध्यम से जंजीर नहीं किया जा सकता है$()
एलेक्स के।

2
@AlexK। उनकी बात यह थी कि वास्तव में कोई भी जंजीर .readyनहीं बनाता क्योंकि यह एक अच्छी तरह से स्थापित मुहावरा नहीं है। यकीन है कि ऐसा करने का कोई सैद्धांतिक मौका है, लेकिन मैंने कभी भी ऐसा करते हुए कोड नहीं देखा है (जो एक अच्छा तर्क नहीं है लेकिन आप जानते हैं: डी)।
एसेलीजा

2
हो सकता है क्योंकि इस सैद्धांतिक मौका विधि की सिफारिश नहीं की गई है , क्योंकि इसमें अलग-अलग रिलीज में अलग व्यवहार है।
VisioN

3

संभावना से अधिक यह सिर्फ एक दस्तावेज बग है और इसे ठीक किया जाना चाहिए, इसका उपयोग करने के लिए केवल नकारात्मक पक्ष $().ready(handler)यह पठनीयता है। यकीन है, बहस है कि $(handler)बस के रूप में अपठनीय है। मैं सहमत हूं, इसीलिए मैं इसका उपयोग नहीं करता

आप यह भी तर्क दे सकते हैं कि एक विधि दूसरे की तुलना में तेज है। हालाँकि, किसी अंतर को नोटिस करने के लिए आप कितनी बार एकल पृष्ठ पर एक पंक्ति में इस विधि को पर्याप्त बार कॉल करते हैं?

अंतत: यह व्यक्तिगत प्राथमिकता पर आ जाता है। $().ready(handler)पठनीयता तर्क के अलावा अन्य उपयोग करने के लिए कोई नकारात्मक पहलू नहीं है। मुझे लगता है कि इस मामले में प्रलेखन मिस-लीडिंग है।


+1! आप बिलकुल सही थे! आप आधिकारिक jQuery के उत्तर को पढ़ना पसंद करेंगे। मैंने इसे एक उत्तर के रूप में जोड़ा।
गेदरॉन

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: अपरिभाषित

एसओ, केवल हैंडलर और डॉक्टर संस्करण उपयोग के कुछ वापस करने के jQuery सम्मेलन के साथ संगत हैं क्योंकि वे दस्तावेज़ चयनकर्ता प्राप्त करते हैं और पास किए गए फॉर्म के साथ आपको कुछ वापस करना होगा (मैं ऐसा नहीं करूंगा जो मुझे लगता है, लेकिन इसे बस में डाल दें दिखाने के लिए "अंदर" यह कुछ है)।

यहाँ जिज्ञासु के लिए इसका एक संस्करण है: http://jsfiddle.net/az85G/


मैं नहीं देख सकते हैं क्या है कि यह कुछ भी नहीं मिल रहा है के साथ समस्या यह है, संदर्भ आप jQuery के लिए दिया जाता है nullतो .find('*').lengthलौट 0 । क्या आपको इस (स्पष्ट) व्यवहार के साथ कुछ बुरा लगता है?
गॉर्डन मोनिका

@gdoron - मुझे इस व्यवहार के साथ कुछ भी बुरा नहीं लगता है, मैं केवल इस बात की तुलना में अंतर को इंगित करना चाहता था कि यह एक चयनकर्ता है जो शून्य नहीं है - ध्यान दें कि इस खाली चयनकर्ता की संभावना है कि "तेज" टिप्पणियां नोट की गई हैं कहीं और के रूप में यह प्रक्रिया करने के लिए एक छोटी सी वस्तु है, लेकिन एक वस्तु वापस नहीं करता है और उस उदाहरण में "अपरिभाषित" नहीं है। मैं वास्तव में इस सवाल को पसंद करता हूं और इसे बढ़ा दिया है :)
मार्क शुल्त्स

इसका कारण यह है कि यह तेज है, क्योंकि ctor की पहली "ब्रेक" स्थिति है if(!selector) return thisयदि आप कुछ और देते हैं, तो कुछ और regexचीजें चल रही हैं ... कृपया अच्छे शब्दों के लिए धन्यवाद ... मुझे लगता है कि मैं jQuery टीम से पूछ सकता हूं इसका उत्तर दो (नरक, यह मेरा पुस्तकालय नहीं है :-))।
गॉर्डन मोनिका का

हां, मैंने कोड बेस के इस विशेष भाग का अध्ययन नहीं किया है, मैंने बग के लिए इंटरम फिक्स में डालने के लिए कोर को हैक किया है, लेकिन उस हिस्से को नहीं। मैं jQuery(document).ready(function(){});वर्तमान में हमारे कोड बेस में फॉर्म को देखना पसंद करता हूं क्योंकि jQuery विशेषज्ञता के विभिन्न स्तर हैं और यह नए लोगों के लिए "सबसे स्पष्ट" है कि यह jQuery के लिए एक इवेंट हैंडलर फ़ंक्शन है।
मार्क शुल्त्स

0

मुझे लगता है कि यह वास्तव में पठनीयता के लिए और कुछ से अधिक है।

यह एक अभिव्यंजक के रूप में नहीं है

$().ready(handler);

जैसा

$(document).ready(handler)

शायद वे मुहावरेदार jQuery के कुछ रूप को बढ़ावा देने की कोशिश कर रहे हैं।


3
$(document).ready(handler)अधिक पठनीय है, $(handler)जिसकी आईएस ने सिफारिश की है ...
गॉर्डन मोनिका का
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.