स्व-संदर्भित अनाम समापन: जावास्क्रिप्ट अपूर्ण है?


18

क्या तथ्य यह है कि अनाम स्वयं-संदर्भित फ़ंक्शन क्लोजर जावास्क्रिप्ट में बहुत अधिक प्रचलित हैं, यह सुझाव देता है कि जावास्क्रिप्ट एक अधूरा विनिर्देश है? हम इसे बहुत देखते हैं:

(function () { /* do cool stuff */ })();

और मुझे लगता है कि सब कुछ स्वाद का मामला है, लेकिन क्या यह एक कीचड़ की तरह नहीं दिखता है, जब आप चाहते हैं कि यह एक निजी नाम स्थान है? क्या जावास्क्रिप्ट पैकेज और उचित कक्षाएं लागू नहीं कर सकता है?

एक्शनस्क्रिप्ट 3 की तुलना, ईसीएमएस्क्रिप्ट पर भी आधारित है, जहां आपको मिलता है

package com.tomauger {
  import bar;
  class Foo {
     public function Foo(){
       // etc...
     }

     public function show(){
       // show stuff
     }

     public function hide(){
       // hide stuff
     }
     // etc...
  }
}

हमारे द्वारा जावास्क्रिप्ट में किए जाने वाले संकल्पों के विपरीत (यह jQuery प्लगइन संलेखन दस्तावेज से ):

(function( $ ){

  var methods = {
    init : function( options ) { // THIS },
    show : function( ) { // IS   },
    hide : function( ) { // GOOD },
    update : function( content ) { // !!! }
  };

  $.fn.tooltip = function( method ) {

    // Method calling logic
    if ( methods[method] ) {
      return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
    } else if ( typeof method === 'object' || ! method ) {
      return methods.init.apply( this, arguments );
    } else {
      $.error( 'Method ' +  method + ' does not exist on jQuery.tooltip' );
    }    

  };

})( jQuery );

मैं सराहना करता हूं कि यह प्रश्न प्राथमिकताओं और प्रोग्रामिंग शैलियों के बारे में एक शेख़ी में आसानी से बदल सकता है, लेकिन मैं वास्तव में यह सुनने के लिए बहुत उत्सुक हूं कि आपने अनुभवी प्रोग्रामरों को इस बारे में कैसा महसूस किया है और क्या यह स्वाभाविक लगता है, जैसे कि एक नई भाषा के अलग-अलग आइडिओसिप्रेसिस सीखना, या कुल्डी। , कुछ बुनियादी प्रोग्रामिंग भाषा घटकों के लिए वर्कअराउंड की तरह, जो अभी लागू नहीं हुए हैं?


22
"जावास्क्रिप्ट लागू नहीं कर सका ... उचित वर्ग?" नहीं। यह पहले से ही उचित प्रोटोटाइप है। प्रोटोटाइप कक्षाओं से नीच नहीं हैं। वे भिन्न हैं। लोगों ने कई बार जावास्क्रिप्ट में कक्षाएं जोड़ने की कोशिश की और असफल रहे हैं।
रीन हेनरिक्स

5
@ रीन: और फिर भी किसी तरह एक्शनस्क्रिप्ट ने इसे प्रबंधित किया ...
मेसन व्हीलर

8
@ वहाँ "अंतर्निहित कक्षाएं" नहीं हैं। एक प्रोटोटाइप भाषा में एक वर्ग के रूप में ऐसी कोई चीज नहीं है । आप दो प्रतिमानों को उलझाते रहते हैं।
रीइन हेनरिक

1
मुझे व्यक्तिगत रूप से अनाम फ़ंक्शन भाषा की सुविधा कक्षाओं की तुलना में अधिक लचीली लगती है। हालाँकि मुझे कार्यात्मक प्रोग्रामिंग पसंद है जिसमें यह मुहावरा आम है।
आहारबुद्ध २

1
दूसरों के लिए, यहां: brianodell.net/?page_id=516 जावास्क्रिप्ट पर एक प्रोटोोटाइपल भाषा के रूप में एक भयानक प्राइमर है।
टॉम ऑर्नर

जवाबों:


9

मुझे लगता है कि सब कुछ स्वाद का मामला है, लेकिन क्या यह एक कीचड़ की तरह नहीं दिखता है, जब आप चाहते हैं कि एक निजी नाम स्थान है? क्या जावास्क्रिप्ट पैकेज और उचित कक्षाएं लागू नहीं कर सकता है?

अधिकांश टिप्पणियों में मिथक के खिलाफ तर्क दिया गया है कि "प्रोटोटाइप गरीब आदमी की कक्षाएं हैं", इसलिए मैं सिर्फ दोहराता हूं कि प्रोटोटाइप-आधारित OO वर्ग-आधारित OO से किसी भी तरह से नीच नहीं है।

दूसरा बिंदु "एक कीचड़ जब आप सभी इसे एक निजी नामस्थान चाहते हैं"। आपको जानकर हैरानी होगी कि स्कीम्स को परिभाषित करने के लिए स्कीम ठीक उसी कीचड़ का उपयोग करती है। यह शाब्दिक रूप से अच्छी तरह से किए गए डांट के कट्टरपंथी उदाहरण बनने से नहीं रोका गया।

बेशक, स्कीम में मैक्रों के पीछे 'कीचड़' छिपा है ...।


1
आप अपने दावे का समर्थन करने के लिए कोई सबूत पेश नहीं करते हैं कि यह योजना शाब्दिक रूप से अच्छी तरह से किए गए स्कोपिंग का प्राथमिक उदाहरण है, या यह कि स्कोप को परिभाषित करने के लिए योजना के कार्यों का उपयोग करने के लिए कुछ भी नहीं है।
डेडएमजी

स्कीम के लिए एक उदाहरण के रूप में बात नहीं कर सकते, लेकिन जेएस के सह-निर्माता ब्रेंडन
ईच के

7

सबसे पहले, कुछ बातें:

  1. जावास्क्रिप्ट को देखने का दूसरा तरीका 1 मिलियन और 1 चीजें हैं जो आप एक निर्माण के रूप में फ़ंक्शन के साथ कर सकते हैं। यह सब वहाँ है यदि आप इसे खोजते हैं। यह सिर्फ एक समारोह से दूर नहीं है।

  2. यह jQuery प्लग-इन संलेखन बात भयानक है। मुझे नहीं पता कि वे इसकी वकालत क्यों कर रहे हैं। $ एक्सटेंशन सामान्य-उपयोग वाले सामान होने चाहिए जो $ पहले से ही बहुत अच्छी तरह से कवर किए गए हैं जो बिल्ड-मी-ए-पूर्ण-विजेट विधियों में शामिल नहीं हैं। यह एक DOM-API नॉर्मलाइज़ेशन टूल है। इसका उपयोग आपकी अपनी वस्तुओं के अंदर सबसे अच्छा दफन है। मैं इसे पूर्ण यूआई पुस्तकालय भंडार के रूप में उपयोग करने की अपील नहीं देखता हूं।

क्लाइंट साइड वेब पर पैकेज व्यर्थ हैं

व्यक्तिगत रूप से क्लाइंट-साइड वेब पर पैकेज के बारे में मुझे जो पसंद नहीं है, वह यह है कि हम मूल रूप से दिखावा कर रहे हैं कि हम कुछ ऐसा कर रहे हैं जो हम वास्तव में नहीं कर रहे हैं। एक पोस्ट। NET वेबफॉर्म और gobs-of-horrifying-stuff-that-never-panned-out-from-our-Java-दोस्तों की दुनिया में, मैं बल्कि HTML से जुड़े संसाधनों के साथ हंक के बारे में सोचना चाहूंगा कि यह वास्तव में क्या है। और यह कुछ और है का नाटक करके सीखने-नई-चीजों-प्रतिरोधी ओएस ऐप डेवलपर्स को खुश करने की कोशिश न करें। जेएस में क्लाइंट-साइड वेब पर, अज़ैक्स के साथ भयानक कुछ करने के लिए "आयातित" कुछ भी नहीं मिलता है जो ब्राउज़र-कैशिंग की अज्ञानता में संचालित होता है, जो हां, कई लोगों ने करने की कोशिश की है। ब्राउज़र के लिए यह सब मायने रखता है कि इसे या तो लोड किया गया था और व्याख्या की गई थी या यह नहीं था। हमारे पास "सिर्फ मामले में" उपयोग के लिए उपलब्ध क्लाइंट पर अधिक कोड नहीं है अच्छे कारणों के लिए। # 1 जा रहा है कि मैंने सिर्फ वेब ऐप्स के लिए प्लग-इन और ब्राउज़र प्लग-इन निर्भरता का वर्णन किया है क्योंकि एक घटना ने आमतौर पर बहुत अच्छा काम नहीं किया है। हम अब वेब चाहते हैं। इस सप्ताह तीसरी बार एडोब या सन को अपडेट करने के बाद नहीं।

भाषा की संरचना के लिए इसकी क्या आवश्यकता है

जेएस ऑब्जेक्ट अत्यधिक परिवर्तनशील हैं। हम किसी भी हद तक नामस्थान के वृक्ष लगा सकते हैं जो हमें ऐसा करने के लिए उपयोगी लगता है और ऐसा करना बहुत आसान है। लेकिन हां, किसी भी चीज को दोबारा इस्तेमाल करने लायक बनाने के लिए आपको ग्लोबल स्पेस में किसी भी लाइब्रेरी की जड़ से चिपके रहना होगा। सभी निर्भरताएँ वैसे भी एक ही समय में जुड़ी हुई हैं और भरी हुई हैं, इसलिए कुछ और करने का क्या मतलब है? वैश्विक नाम स्थान से बचने की बात यह नहीं है कि कुछ भी बुरा है। यह बहुत अधिक सामान है कि वहाँ बुरा है क्योंकि आप नाम स्थान टकराव या गलती से मुख्य भाषा सुविधाओं को अधिलेखित करने का जोखिम चलाते हैं।

सिर्फ इसलिए कि यह लोकप्रिय है इसका मतलब यह नहीं है कि हम इसे सही कर रहे हैं

अब जब आप यह सब क्लाइंट-साइड वेब ऐप पर देखते हैं:

(function(){
//lots of functions defined and fired and statement code here
})()

समस्या यह नहीं है कि हमारे पास किसी ऐप को बनाने के लिए उपकरणों की कमी है, समस्या यह है कि लोग संरचना का मूल्यांकन नहीं कर रहे हैं। एक डिजाइन एजेंसी पर 2-3 पृष्ठ एक-तरफ़ा अस्थायी फेंकने वाली साइटों के लिए, मुझे वास्तव में इससे कोई समस्या नहीं है। जहां यह बदसूरत हो जाता है, जब आपको कुछ बनाए रखने योग्य और सुपाठ्य और संशोधित करने में आसान होता है।

लेकिन जब आप उस जगह पर पहुंच जाते हैं, जहां बस फिर से उपयोग करने योग्य सभी वस्तुओं और कारखानों को लागू करने का समय होता है और शायद एक या दो नए अस्थायी संस्करण उस प्रक्रिया में रेंग सकते हैं, तो यह एक सुविधा है।

लेकिन पैकेज / मॉड्यूल के साथ जेएस के कार्यान्वयन हैं

ध्यान रखें कि Node.js में, जहां इस तरह की चीजें बहुत अधिक मायने रखती हैं, उनके पास मॉड्यूल हैं। जेएस, यह मानते हुए कि हम uber-config-hell से बच सकते हैं जो अन्य भाषाओं को ग्रस्त करता है, समीकरण में केवल एक चीज है और प्रत्येक निष्पादित फ़ाइल का अपना पृथक दायरा है। लेकिन एक वेब पेज पर, js-file को लिंक करना स्वयं आयात स्टेटमेंट है। मक्खी पर अधिक आयात करना केवल समय और संसाधनों की बर्बादी है क्योंकि संसाधनों को प्राप्त करने के लिए बस फाइलों में लिंक जोड़ने की तुलना में बहुत अधिक प्रयास की आवश्यकता होती है क्योंकि आपको उनकी आवश्यकता होती है यह जानते हुए कि उन्हें एक ब्राउज़र में कैश किया जाएगा यदि किसी अन्य पृष्ठ को फिर से उनकी आवश्यकता है। इसलिए jQuery या अधिक पारंपरिक वस्तुओं जैसे एडेप्टर ऑब्जेक्ट फैक्ट्री बनाने के अलावा कुछ भी करके वैश्विक स्थान को विभाजित करने की कोशिश कर रहा है जो कि किसी दिए गए डोमेन में कार्यों के एक बड़े उपसमूह को कवर करता है, जबकि वैश्विक स्तर पर एक स्थान पर कब्जा है। वहाँ'http://wiki.ecmascript.org/doku.php?id=harmony:modules

तो नहीं, वैश्विक नाम स्थान प्रदूषण से बचने के लिए उपयोग किए जाने वाले ऑटो-इनवोकरों में कुछ भी गलत नहीं है जब ऐसी चीजों का उपयोग करने का एक अच्छा कारण है (अधिक बार नहीं होने की तुलना में)। और हमारे पास हमारी वस्तुओं में लगातार निजी-समतुल्य गुण हैं (बस कंस्ट्रक्टर में एक संस्करण को परिभाषित करें और इसे संपत्ति के रूप में उजागर न करें)।

तथ्य यह है कि हम ऐसा कर सकते हैं, हालांकि, कमाल है। भारी उपयोग एक संकेत है कि जेएस डेवलपर्स अभी भी शायद परिपक्व हो रहे हैं, लेकिन यह किसी के लिए भाषा में एक अंतराल छेद नहीं है जो क्लाइंट-साइड वेब में एक प्रतिमान को मजबूर करने की कोशिश नहीं कर रहा है जो कि यहां समझ में नहीं आता है।


डाउन-वोटर तक, क्या आप कृपया बता सकते हैं कि क्यों? जब कोई यह लिखता है कि मुझे लगता है कि वह एक स्पष्टीकरण का हकदार है!
सांगो

+1 अच्छा उत्तर, सुनिश्चित नहीं है कि नीचे मतदान क्यों हुआ।

बहुत बढ़िया लेखन और महान परिप्रेक्ष्य। मुझे यह भी पसंद है "सिर्फ इसलिए कि यह एक ट्रॉप है इसका मतलब यह नहीं है कि यह सही है।" मुझे लगता है कि मेरा मुद्दा यह है कि मैं कठोर भाषाओं के साथ अधिक सहज हूं, जो (आईएमओ) कई तरीकों से विकास दक्षता में मदद करता है। जावास्क्रिप्ट वास्तव में हार्दिक-इच्छा-सा प्रतीत होता है जिसमें बहुत सारे चेक और बैलेंस नहीं होते हैं: आप जो चाहें कर सकते हैं, इसलिए बाहर का परिदृश्य मुहावरों और प्रथाओं की गड़बड़ी है। अपनी कोडिंग संरचना से संपर्क करने के लिए "सही" तरीके से नाखून करना मुश्किल है। हालांकि मैं मानता हूं कि त्वरित 1-बंद नौकरी के लिए, यह एक बड़ी चिंता नहीं है।
टॉम ऑगर

1
IMO, ऐसी बहुत सी चीजें हैं जो आप अपने आप को लटकाने के अलावा बहुत सी रस्सी के साथ कर सकते हैं और आप सामयिक से-हैंगिंग से तेज कोड लिखना सीखते हैं जो कम-बार होता है क्योंकि आप बेहतर आदतें विकसित करते हैं, लेकिन मैं इसके लिए नाटक नहीं करूंगा हर कोई या हर काम के लिए एक आदर्श उम्मीदवार। मुझे आपके द्वारा इसके बारे में जानने के बारे में अधिक संदेह है, हालांकि, आप इसे जितना अधिक सहनशील पाएंगे। मुझे लगता है कि जब मैं प्रथम श्रेणी के कार्यों या वस्तुओं के रूप में लचीली / उत्परिवर्तित जेएस के रूप में भाषाओं में चीजों को करने की कोशिश कर रहा हूं तो मुझे अपना आधा दिमाग याद आ रहा है।
एरिक रिपेन

4

दूसरी बात जो आप याद कर रहे हैं वह यह है कि जावास्क्रिप्ट को पीछे की ओर संगत होना चाहिए। यदि आप पैकेज सिंटैक्स को पेश करने का प्रयास करते हैं तो यह वास्तव में कुछ पागल तरीकों से वेब को तोड़ सकता है। यह बुरा होगा! डौग क्रॉकफोर्ड ने विभिन्न बिंदुओं पर इस बारे में बात की है और इसे जोड़ने के प्रयास विफल क्यों हुए हैं।


ये एक अच्छा बिंदु है। और फिर भी ActionScript ने इसे प्रबंधित किया, बस एक नया संस्करण डालकर। जब आप स्क्रिप्ट टैग को परिभाषित करते हैं, तो आप हमेशा जावास्क्रिप्ट संस्करण को निर्दिष्ट करने में सक्षम होते हैं, इसलिए मौजूदा साइटों को "तोड़ना" एक गैर-मुद्दा होना चाहिए।
टॉम ऑगर

1
व्यवहार में नेट पर अधिकांश स्क्रिप्ट टैग में संस्करण संख्या नहीं होती है। सच कहूं तो मुझे इस पर सभी मुद्दों पर यकीन नहीं है, लेकिन मुझे पता है कि इस सामान के बारे में सोचने वाले लोगों ने फैसला किया है कि यह उल्लेखनीय नहीं है।
Zachary K

1
@ टॉम: एडोब का फ्लैश प्लेटफॉर्म पर भी पूरा नियंत्रण है। जेएस के सभी प्लेटफार्मों पर किसी एक इकाई का पूर्ण नियंत्रण नहीं है। इसके अलावा, बस एक ब्राउज़र में एक जेएस स्क्रिप्ट के लिए एक संस्करण संख्या से निपटने का मतलब होगा कि आप या तो पुराने ब्राउज़र का समर्थन नहीं कर रहे हैं या दो स्क्रिप्ट लिखना है। इसलिए, यह है एक मुद्दा।
जेरेमी हेइलर

2

हाँ, यह एक कीचड़ है।

बहुत सारे लोग कह रहे हैं कि "प्रोटोटाइप कक्षाओं से नीच नहीं हैं"। मैं असहमत हूं, लेकिन यह वरीयता का मामला है। लेकिन यह भी जावास्क्रिप्ट के साथ वास्तविक समस्या नहीं है - समस्या यह है कि यह मूल रूप से एनिमेटेड बटन जैसी चीजों को बनाने के लिए एक त्वरित और गंदे स्क्रिप्टिंग भाषा के रूप में डिज़ाइन किया गया था। 90 के दशक के मध्य में किसी ने कभी नहीं सोचा था कि जावास्क्रिप्ट को कुछ पागल सामान करने के लिए कहा जाएगा जो अब वह कर रहा है।


6
मैं असहमत हूं, जावास्क्रिप्ट भाषा वास्तव में बहुत बढ़िया है। यह एक निर्दिष्ट और परस्पर-असंगत DOM के तहत एक साथ lumped था, जहां सभी समस्याएं शुरू हुईं।
डीन हार्डिंग

2
प्रोटोटाइप के साथ इसका क्या करना है?
एरिक रेपेन

2

बेनामी सेल्फ-इनवॉइसिंग फ़ंक्शन कक्षाओं की तुलना में मॉड्यूल के लिए अधिक समान हैं। यह कष्टप्रद है कि जावास्क्रिप्ट के लिए डिफ़ॉल्ट वैश्विक दायरे में चलना है। JS.next पर काम करने वाली समिति मॉड्यूल को जोड़ने पर गंभीरता से विचार कर रही है, ताकि आप अपने स्थानीय चरों को वैश्विक दायरे में न छोड़ें। सौभाग्य से, जावास्क्रिप्ट के कार्यों में इस तरह के सुविधाजनक शब्दार्थ हैं कि हम एक गुमनाम फ़ंक्शन को एक निजी दायरे के रूप में सापेक्ष आसानी से उपयोग कर सकते हैं।

मैं यह नहीं देखता कि कक्षाएं वास्तव में चर्चा में कैसे प्रवेश करती हैं, सिवाय इसके कि वे कई भाषाओं में शीर्ष-स्तरीय स्कूपिंग निर्माण हैं। एक बेहतर मॉड्यूल / पैकेज / कृपया-मुझे-एक-स्थानीय-गुंजाइश-तो-मैं-न-छोड़-मेरा-चर-में-वैश्विक-पर्यावरण का निर्माण बहुत अच्छा होगा।


1

आप एक्सटीजेएस 3 और 4 पर एक नज़र रखना चाह सकते हैं, जहाँ वे नेमस्पेस को अच्छी तरह से लागू करने में कामयाब रहे हैं।

- -1 के बाद जोड़ा गया

यहाँ मेरा कहना था, इन सभी 'संकल्पों' को छिपाना संभव है और अभी भी बहुत अनुकूल कोड है जैसे:

Ext.ns('com.tomauger');
Ext.Loader.load('bar.js'); //unfortunately filname needs to be used
MyNameSpace.Foo = {
   //...
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.