`नया फ़ंक्शन ()` जावास्क्रिप्ट में कम मामले "च" के साथ


106

मेरे सहयोगी जावास्क्रिप्ट में नई वस्तुओं को परिभाषित करने के लिए "कम मामले" च "के साथ" नए फ़ंक्शन () "का उपयोग कर रहे हैं। यह सभी प्रमुख ब्राउज़रों में अच्छा काम करता है और यह निजी चर को छुपाने में काफी प्रभावी भी लगता है। यहाँ एक उदाहरण है:

    var someObj = new function () {
        var inner = 'some value';
        this.foo = 'blah';

        this.get_inner = function () {
            return inner;
        };

        this.set_inner = function (s) {
            inner = s;
        };
    };

जैसे ही "इस" का उपयोग किया जाता है, यह someObj की सार्वजनिक संपत्ति बन जाता है। तो कुछObj.foo, someObj.get_inner () और someObj.set_inner () सभी सार्वजनिक रूप से उपलब्ध हैं। इसके अलावा, set_inner () और get_inner () विशेषाधिकार प्राप्त तरीके हैं, इसलिए उनके पास क्लोजर के माध्यम से "आंतरिक" तक पहुंच है।

हालाँकि, मैंने कहीं भी इस तकनीक का कोई संदर्भ नहीं देखा है। यहां तक ​​कि डगलस क्रॉफोर्ड की JSLint इसके बारे में शिकायत करती है:

  • अजीब निर्माण। 'नया' हटाएं

हम उत्पादन में इस तकनीक का उपयोग कर रहे हैं और यह अच्छी तरह से काम कर रहा है, लेकिन मैं इसके बारे में थोड़ा चिंतित हूं क्योंकि यह कहीं भी प्रलेखित नहीं है। किसी को पता है कि क्या यह एक वैध तकनीक है?


6
मैं IIFE ('तत्काल-इनवॉक्ड फंक्शन') पर आपके निर्माण को प्राथमिकता देता हूं। 1: आपको एक स्पष्ट 'इंस्टेंस' ऑब्जेक्ट की आवश्यकता नहीं है, यह वही है जो जावास्क्रिप्ट में है। 2: आपको कुछ भी वापस करने की आवश्यकता नहीं है, जिसका अर्थ है, आपको याद रखने की आवश्यकता नहीं है। यहां तक ​​कि स्वीकृत उत्तर के लेखक शुरू में उदाहरण वस्तु को वापस करना भूल गए! लोग आमतौर पर IIFE का उपयोग करना पसंद करते हैं यदि वे नए और इससे नफरत करते हैं, तो अच्छे कारण के साथ - यदि आपके पास DOM ईवेंट को हैंडल करने वाला कोई फ़ंक्शन है, तो thisउस ईवेंट को संदर्भित करेगा , जो ईवेंट को निकाल दिया गया था, आपकी वस्तु नहीं, बल्कि आप var instance = thisइसके बजाय बस हो सकते हैं ।
ली कोवलकोव्स्की

1
"लोअर केस एफ" को निर्दिष्ट करना सवाल क्यों महत्वपूर्ण है?
क्लियरक्लाउड 8

7
क्योंकि जावास्क्रिप्ट में भी 'फंक्शन' फ़ंक्शन (अपरकेस एफ के साथ) मौजूद होता है, जो अलग है: फ़ंक्शन एक कंस्ट्रक्टर फ़ंक्शन है जो नए फ़ंक्शन ऑब्जेक्ट बना सकता है, जबकि फ़ंक्शन एक कीवर्ड है।
स्टिजन डे विट


@ बर्गी मैंने आपके लिंक पढ़े। मुझे इस पैटर्न को बदनाम करने का कोई कारण नहीं दिखता। यह मान्य है। यह आसान है। तो क्या गलत हुआ। JSLint BTW :) सब कुछ के बारे में शिकायत करता है:
Stijn de Witt

जवाबों:


64

मैंने उस तकनीक को पहले देखा है, यह मान्य है, आप एक फ़ंक्शन एक्सप्रेशन का उपयोग कर रहे हैं जैसे कि यह एक कंस्ट्रक्टर फंक्शन था

लेकिन IMHO, आप एक ऑटो-इनवोकेशन फंक्शन एक्सप्रेशन के साथ इसे प्राप्त कर सकते हैं, मैं वास्तव newमें उस तरह से ऑपरेटर का उपयोग करने की बात नहीं देखता :

var someObj = (function () {
    var instance = {},
        inner = 'some value';

    instance.foo = 'blah';

    instance.get_inner = function () {
        return inner;
    };

    instance.set_inner = function (s) {
        inner = s;
    };

    return instance;
})();

newऑपरेटर का उद्देश्य नई वस्तु उदाहरण बनाना है, [[Prototype]]आंतरिक संपत्ति की स्थापना करना , आप देख सकते हैं कि यह [Construct]आंतरिक संपत्ति द्वारा कैसे बनाया गया है ।

उपरोक्त कोड एक बराबर परिणाम देगा।


1
धारा 13 में ईसीएमएस्क्रिप्ट 262 की विशिष्टता इसे औपचारिक रूप से समझाती है। function foo () {}एक Functionवस्तु बनाने का परिणाम जैसा कुछ होता है [संभवतः नए कार्य () के साथ]। यह सिंटेक्स चीनी है।
क्लिंटन पियर्स

3
मुझे लगता है कि आप return instance;अंत में याद कर रहे हैं । नहीं someObjतो बस हो जाएगा undefined। :-)
मैथ्यू क्रुमले

1
क्या मैं आपको सुझाव दूंगा कि यदि आप प्रतिरूपकता और जानकारी को छिपाने के बारे में परवाह करते हैं, तो आप बस इस पर ध्यान देते हैं और आवश्यकता के अनुसार कुछ का उपयोग करना शुरू करते हैं। तुम वहाँ आधे रास्ते में हो, यहाँ क्यों रुकोगे? एसिंक्रोनस मॉड्यूल परिभाषा (जो की आवश्यकता है ।js लागू होती है) इस usecase का समर्थन करती है और आपको स्कूपिंग, नेमस्पेसिंग और निर्भरता प्रबंधन से निपटने के लिए एक पूरा टूलसेट देती है।
स्टिजन डे विट

ध्यान दें कि फ़ंक्शन घोषणा के आसपास के कोष्ठक अनावश्यक हैं क्योंकि बयान पहले से ही एक अभिव्यक्ति की उपस्थिति के कारण है=
विस्फोट गोलियां

@StijndeWitt आधे रास्ते का मतलब है कि आपको आवश्यकता का उपयोग करने के लिए दो बार काम करने की आवश्यकता होगी। लेकिन साधारण मामलों में आपको इसकी आवश्यकता हो सकती है।
xr280xr

15

आपका कोड कम अजीब निर्माण के समान है

function Foo () {
    var inner = 'some value';
    this.foo = 'blah';

    ...
};
var someObj = new Foo;

9
यह केवल समान नहीं है, यह बिल्कुल वैसा ही काम करता है ... एकमात्र अपवाद के साथ कि वे किसी अन्य ऑब्जेक्ट को बनाने के लिए फू का पुन: उपयोग नहीं कर पाएंगे।
किकिटो

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

@kikito आपका क्या मतलब है यह किसी अन्य वस्तु को बनाने के लिए फू का पुन: उपयोग करने की अनुमति नहीं देता है? var newObj = नया फू () एक नया उदाहरण बनाना चाहिए।
बिल यांग

1
@ बेल्यंग जो 5 साल पहले था। कोई जानकारी नहीं। मैंने तब से जावास्क्रिप्ट नहीं छुआ है।
किकिटो

12

कुछ पहलुओं को स्पष्ट करने के लिए और डगलस क्रॉकफोर्ड के JSLint को अपने कोड के बारे में शिकायत नहीं करने के लिए यहां बताएं कि तात्कालिकता के कुछ उदाहरण हैं:

1. o = new Object(); // normal call of a constructor

2. o = new Object;   // accepted call of a constructor

3. var someObj = new (function () {  
    var inner = 'some value';
    this.foo = 'blah';

    this.get_inner = function () {
        return inner;
    };

    this.set_inner = function (s) {
        inner = s;
    };
})(); // normal call of a constructor

4. var someObj = new (function () {  
    var inner = 'some value';
    this.foo = 'blah';

    this.get_inner = function () {
        return inner;
    };

    this.set_inner = function (s) {
        inner = s;
    };
}); // accepted call of a constructor

उदाहरण में 3. मान के रूप में (...) एक फ़ंक्शन / कंस्ट्रक्टर है। यह इस तरह दिखता है: नया (फ़ंक्शन () {...}) ()। इसलिए यदि हम उदाहरण 2 में समाप्त कोष्ठक को छोड़ते हैं, तो अभिव्यक्ति अभी भी एक वैध रचनाकार कॉल है और उदाहरण 4 की तरह दिखता है।

डगलस क्रॉफोर्ड की जेएसएलआईएनटी "सोचती है" आप फ़ंक्शन को someObj पर असाइन करना चाहते थे, न कि इसका उदाहरण। और आखिर यह सिर्फ एक चेतावनी है, त्रुटि नहीं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.