आईआईएफई को समझना

मुझे "तुरंत-आमंत्रित फ़ंक्शन अभिव्यक्ति" (आईआईएफई) समझने में बहुत कठिनाई हो रही है।

मैं एक गेम तैयार करने की कोशिश कर रहा हूं (मेरे पास अभी एक कामकाजी मॉडल है, लेकिन यह ऑब्जेक्ट उन्मुख नहीं है और मेरा लक्ष्य कोड को बेहतर डिजाइन और कार्यान्वित करना है), और मुझे बताया गया कि मेरा ऑब्जेक्ट संदर्भ वैश्विक नहीं है।

मेरे पास अभी क्या है।

var engine = new _engine();
engine.count++; //there's a lot more to the engine, I just haven't converted it yet

मैंने जो कोशिश की है वह यहां है:

(function() { var engine = new _engine(); }());
engine.count++; //error, engine is not defined

तो अब मैं यह कोशिश कर रहा हूं, और यह काम करता है, लेकिन मुझे डर है कि यह अभी भी वैश्विक हो सकता है!

var engine = (function(){ return new _engine(); }());
engine.count++; //works, but is this still global?

जावास्क्रिप्ट में ऑब्जेक्ट डिज़ाइन मेरे लिए एक बहुत ही नई अवधारणा है, इसलिए मैं पूरी तरह से यह सुनिश्चित करना चाहता हूं कि यह समझने के लिए मैं सही तरीके से सीख रहा हूं, यह समझने के साथ कि यह क्यों काम कर रहा है।

कृपया ध्यान दें कि मुझे पृष्ठ में कहीं से भी इंजन तक पहुंचने में सक्षम होना चाहिए। क्या इससे वैश्विक की आवश्यकता होती है? ग्लोबल इतने डूब गए क्यों हैं? (अन्य ऑब्जेक्ट फ़ंक्शन रिटर्न और बूलियन चर के आधार पर इंजन का संदर्भ देते हैं)

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

2 उत्तर

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

बाहरी सुप्रसिद्ध चर पर निर्भर होने के बजाय आप वस्तुओं में निर्भरताओं को इंजेक्ट करने के लिए निर्माण समय (या इंजेक्टर का उपयोग करके) पर निर्भरता इंजेक्शन का उपयोग कर सकते हैं।

यदि आप मॉड्यूलर कोड लिखने के बारे में वास्तव में गंभीर हैं, तो RequJS पर एक नज़र डालें।

Engine.js

(function (ns) {
    function Engine() {
    }

    Engine.prototype.someMethod = function() {
    };

    ns.Engine = Engine;
})(window.myNamespace = window.myNamespace || {});

Game.js

(function (ns) {
    function Game(engine) {
        this._engine = engine;
    }

    Game.prototype.start = function() {
        this._engine.someMethod();
    };

    ns.Game = Game;
})(window.myNamespace = window.myNamespace || {});

app.js

//kickstart your app
(function() {
    var engine = new myNamespace.Engine(),

        //init the Game while injecting the engine dependency
        game = new myNamespace.Game(engine);

    game.start();
})();
1
जोड़ा

मुझे लगता है कि आप निम्न की तलाश में हैं:

(function() {
    var engine = new _engine();
    engine.count++;
   //all other code depending on engine should be in here as well
})();

आपका कोड आपके मूल संस्करण के समान ही काम करेगा, लेकिन अब इंजन वैश्विक होने की बजाय आईआईएफई के लिए स्थानीय है।

edit: After the discussion in comments, it sounds like you really do need engine to be global. In this case you are probably fine leaving your code the way it is, but to make sure you aren't exposing any other variables as globals besides engine you could do something like the following:

var engine = (function() {
   var engine = new _engine();
   engine.count++;
  //any other code from your engine file (probably the _engine definition, etc)

   return engine; //return local engine from the IIFE
})();

या वैकल्पिक रूप से (यह वही है जो jQuery और कुछ अन्य लोकप्रिय पुस्तकालयों का उपयोग करते हैं):

(function(window) {
   var engine = new _engine();
   engine.count++;
  //any other code from your engine file (probably the _engine definition, etc)

   window.engine = engine; //assign engine to window.engine to make it global
})(window);
1
जोड़ा
लेकिन अगर मुझे विभिन्न स्थानों में विभिन्न इंजन कार्यों और चर को निष्पादित करने की आवश्यकता है, तो मैं यह कैसे कर सकता हूं? मैं केवल एक बार new _engine() का उपयोग करना चाहता हूं, और इसे संदर्भित करने में सक्षम हूं जहां मुझे आवश्यकता है।
जोड़ा लेखक Sterling Archer, स्रोत
हालांकि यह एक अच्छा डिजाइन होगा? मुझे बताया गया था कि ग्लोबल्स खराब अभ्यास हैं
जोड़ा लेखक Sterling Archer, स्रोत
मुझे नहीं लगता कि यह संभव है, अन्य वस्तुओं को इंजन ऑब्जेक्ट को इंगित करने की आवश्यकता होगी और मैं इसे एक आईआईएफई में फेंक नहीं सकता हूं।
जोड़ा लेखक Sterling Archer, स्रोत
आह, लेकिन मेरे पास प्रत्येक ऑब्जेक्ट के लिए अलग-अलग फाइलें होंगी डी:
जोड़ा लेखक Sterling Archer, स्रोत
वैश्विक नामस्थान @ एफजे जे प्रदूषण कभी जरूरी नहीं है। आप ऑब्जेक्ट्स को नेमस्पेसिंग करके और निर्भरता इंजेक्शन का उपयोग करके क्या करने की कोशिश कर रहे हैं।
जोड़ा लेखक plalx, स्रोत
या तो उस कोड को आईआईएफई में भी डालें, या बस अपने कोड को अपने पहले ब्लॉक में छोड़ दें।
जोड़ा लेखक Andrew Clark, स्रोत
हां, शायद यह सब कुछ आईआईएफई में रखना बेहतर होगा।
जोड़ा लेखक Andrew Clark, स्रोत
मान लें कि आपका सभी कोड एक फ़ाइल में है, आप लगभग निश्चित रूप से केवल (function() { अपने सभी कोड और }) (); इसके बाद जोड़ सकते हैं। ग्लोबल नेमस्पेस के प्रदूषण के साथ सबकुछ एक ही तरह से काम करेगा।
जोड़ा लेखक Andrew Clark, स्रोत