javascript - हरण - हिंदी में जावास्क्रिप्ट परिचय




मैं जावास्क्रिप्ट में नेमस्पेस कैसे घोषित करूं? (18)

मैं जावास्क्रिप्ट में नेमस्पेस कैसे बना सकता हूं ताकि मेरी ऑब्जेक्ट्स और फ़ंक्शंस अन्य समान नामित ऑब्जेक्ट्स और फ़ंक्शंस द्वारा ओवरराइट नहीं किए जा सकें? मैंने निम्नलिखित का उपयोग किया है:

if (Foo == null || typeof(Foo) != "object") { var Foo = new Object();}

क्या ऐसा करने का एक और सुरुचिपूर्ण या संक्षिप्त तरीका है?


क्या ऐसा करने का एक और सुरुचिपूर्ण या संक्षिप्त तरीका है?

हाँ। उदाहरण के लिए:

var your_namespace = your_namespace || {};

तो आप कर सकते हैं

var your_namespace = your_namespace || {};
your_namespace.Foo = {toAlert:'test'};
your_namespace.Bar = function(arg) 
{
    alert(arg);
};
with(your_namespace)
{
   Bar(Foo.toAlert);
}

Ionuţ जी स्टेन के जवाब का काफी अनुवर्ती, लेकिन var ClassFirst = this.ClassFirst = function() {...} का उपयोग करके var ClassFirst = this.ClassFirst = function() {...} कोड के लाभ दिखा रहा है, जो कक्षाओं के लिए कम नामस्थान अव्यवस्था के लिए जावास्क्रिप्ट के बंद होने का लाभ उठाता है एक ही नामस्थान में।

var Namespace = new function() {
    var ClassFirst = this.ClassFirst = function() {
        this.abc = 123;
    }

    var ClassSecond = this.ClassSecond = function() {
        console.log("Cluttered way to access another class in namespace: ", new Namespace.ClassFirst().abc);
        console.log("Nicer way to access a class in same namespace: ", new ClassFirst().abc);
    }
}

var Namespace2 = new function() {
    var ClassFirst = this.ClassFirst = function() {
        this.abc = 666;
    }

    var ClassSecond = this.ClassSecond = function() {
        console.log("Cluttered way to access another class in namespace: ", new Namespace2.ClassFirst().abc);
        console.log("Nicer way to access a class in same namespace: ", new ClassFirst().abc);
    }
}

new Namespace.ClassSecond()
new Namespace2.ClassSecond()

आउटपुट:

Cluttered way to access another class in namespace: 123
Nicer way to access a class in same namespace: 123
Cluttered way to access another class in namespace: 666
Nicer way to access a class in same namespace: 666


ऐसा करने का एक और तरीका, जिसे मैं ऑब्जेक्ट शाब्दिक रूप से थोड़ा कम प्रतिबंधित मानता हूं, यह है:

var ns = new function() {

    var internalFunction = function() {

    };

    this.publicFunction = function() {

    };
};

उपर्युक्त मॉड्यूल पैटर्न की तरह काफी है और चाहे आप इसे पसंद करते हैं या नहीं , यह आपको किसी ऑब्जेक्ट की कठोर संरचना से बचने के दौरान, अपने सभी कार्यों को सार्वजनिक रूप से बेनकाब करने की अनुमति देता है।


नमूना:

var namespace = {};
namespace.module1 = (function(){

    var self = {};
    self.initialized = false;

    self.init = function(){
        setTimeout(self.onTimeout, 1000)
    };

    self.onTimeout = function(){
        alert('onTimeout')
        self.initialized = true;
    };

    self.init(); /* If it needs to auto-initialize, */
    /* You can also call 'namespace.module1.init();' from outside the module. */
    return self;
})()

आप वैकल्पिक रूप से एक local वैरिएबल घोषित कर सकते हैं, जैसे self और local असाइन local.onTimeout अगर आप इसे निजी बनाना चाहते हैं तो local.onTimeout


मुझे यह पसंद है:

var yourNamespace = {

    foo: function() {
    },

    bar: function() {
    }
};

...

yourNamespace.foo();

मैं एंटरप्राइज़ jQuery साइट पर मिले दृष्टिकोण का उपयोग करता हूं:

यहां उनका उदाहरण दिखाया गया है कि निजी और सार्वजनिक संपत्तियों और कार्यों को कैसे घोषित किया जाए। सब कुछ एक स्व-निष्पादन अज्ञात समारोह के रूप में किया जाता है।

(function( skillet, $, undefined ) {
    //Private Property
    var isHot = true;

    //Public Property
    skillet.ingredient = "Bacon Strips";

    //Public Method
    skillet.fry = function() {
        var oliveOil;

        addItem( "\t\n Butter \n\t" );
        addItem( oliveOil );
        console.log( "Frying " + skillet.ingredient );
    };

    //Private Method
    function addItem( item ) {
        if ( item !== undefined ) {
            console.log( "Adding " + $.trim(item) );
        }
    }
}( window.skillet = window.skillet || {}, jQuery ));

तो यदि आप सार्वजनिक सदस्यों में से किसी एक को एक्सेस करना चाहते हैं तो आप skillet.fry() या skillet.ingredients

वास्तव में अच्छा क्या है कि अब आप सटीक उसी वाक्यविन्यास का उपयोग करके नामस्थान का विस्तार कर सकते हैं।

//Adding new Functionality to the skillet
(function( skillet, $, undefined ) {
    //Private Property
    var amountOfGrease = "1 Cup";

    //Public Method
    skillet.toString = function() {
        console.log( skillet.quantity + " " +
                     skillet.ingredient + " & " +
                     amountOfGrease + " of Grease" );
        console.log( isHot ? "Hot" : "Cold" );
    };
}( window.skillet = window.skillet || {}, jQuery ));

तीसरा undefined तर्क

तीसरा, undefined तर्क मान के चर के undefined स्रोत का स्रोत है। मुझे यकीन नहीं है कि यह आज भी प्रासंगिक है, लेकिन पुराने ब्राउज़र / जावास्क्रिप्ट मानकों (ecmascript 5, जावास्क्रिप्ट <1.8.5 ~ फ़ायरफ़ॉक्स 4) के साथ काम करते समय, ग्लोबल-स्कोप वैरिएबल undefined लिखने योग्य है, इसलिए कोई भी इसके मूल्य को फिर से लिख सकता है। तीसरा तर्क (जब कोई मान नहीं पारित किया जाता है) एक चर नामक undefined बनाता है जिसे नामस्थान / फ़ंक्शन पर स्कॉप्ड किया जाता है। क्योंकि जब आप नाम स्थान बनाते हैं तो कोई मान पारित नहीं होता है, यह मान को undefined मान पर डिफ़ॉल्ट करता है।


मैं आमतौर पर इसे बंद करने में बनाता हूं:

var MYNS = MYNS || {};

MYNS.subns = (function() {

    function privateMethod() {
        // Do private stuff, or build internal.
        return "Message";
    }

    return {
        someProperty: 'prop value',
        publicMethod: function() {
            return privateMethod() + " stuff";
        }
    };
})();

इस लेखन के बाद से वर्षों में मेरी शैली में एक सूक्ष्म परिवर्तन आया है, और अब मैं खुद को इस तरह बंद करने के बारे में लिखता हूं:

var MYNS = MYNS || {};

MYNS.subns = (function() {
    var internalState = "Message";

    var privateMethod = function() {
        // Do private stuff, or build internal.
        return internalState;
    };
    var publicMethod = function() {
        return privateMethod() + " stuff";
    };

    return {
        someProperty: 'prop value',
        publicMethod: publicMethod
    };
})();

इस तरह से मुझे सार्वजनिक एपीआई और कार्यान्वयन को समझने में आसान लगता है। कार्यान्वयन के लिए सार्वजनिक इंटरफ़ेस होने के रूप में वापसी विवरण के बारे में सोचें।


मैं नामस्थान के लिए निम्नलिखित वाक्यविन्यास का उपयोग करता हूं।

var MYNamespace = MYNamespace|| {};

 MYNamespace.MyFirstClass = function (val) {
        this.value = val;
        this.getValue = function(){
                          return this.value;
                       };
    }

var myFirstInstance = new MYNamespace.MyFirstClass(46);
alert(myFirstInstance.getValue());

jsfiddle: http://jsfiddle.net/rpaul/4dngxwb3/1/


मैं पार्टी के लिए 7 साल देर से हूं, लेकिन इस 8 साल पहले काफी काम किया था:

जावास्क्रिप्ट ग्लोबल नेमस्पेस (नेमस्पेस प्रदूषण को रोकने) का सम्मान करते समय, और ऐसा करने के दौरान नेमस्पेस पथ में मौजूद किसी भी मौजूदा ऑब्जेक्ट को क्लॉबर्ड करने के साथ, जटिल वेब एप्लिकेशन को संगठित और प्रबंधित करने के लिए कई घोंसला वाले नामस्थानों को आसानी से और कुशलता से बनाने में सक्षम होना महत्वपूर्ण है। ।

उपरोक्त से, यह मेरा लगभग -2008 समाधान था:

var namespace = function(name, separator, container){
  var ns = name.split(separator || '.'),
    o = container || window,
    i,
    len;
  for(i = 0, len = ns.length; i < len; i++){
    o = o[ns[i]] = o[ns[i]] || {};
  }
  return o;
};

यह नामस्थान नहीं बना रहा है, लेकिन नामस्थान बनाने के लिए एक फ़ंक्शन प्रदान करता है।

यह एक मिनीफार्मर एक लाइनर के लिए संघनित किया जा सकता है:

var namespace=function(c,f,b){var e=c.split(f||"."),g=b||window,d,a;for(d=0,a=e.length;d<a;d++){g=g[e[d]]=g[e[d]]||{}}return g};

उपयोग का उदाहरण:

namespace("com.example.namespace");
com.example.namespace.test = function(){
  alert("In namespaced function.");
};

या, एक बयान के रूप में:

namespace("com.example.namespace").test = function(){
  alert("In namespaced function.");
};

या तो तब निष्पादित किया जाता है:

com.example.namespace.test();

यदि आपको विरासत ब्राउज़र के लिए समर्थन की आवश्यकता नहीं है, तो एक अद्यतन संस्करण:

const namespace = function(name, separator, container){
    var o = container || window;
    name.split(separator || '.').forEach(function(x){
        o = o[x] = o[x] || {};
    });
    return o;
};

अब, मैं namespace को वैश्विक नामस्थान में उजागर करने के लिए तैयार हूं। (बहुत खराब आधार भाषा हमारे लिए यह उपलब्ध नहीं कराती है!) तो मैं आमतौर पर इसे बंद करने में उपयोग करता हूं, जैसे कि:

(function(){
	const namespace = function(name, separator, container){
		var o = container || window;
		name.split(separator || '.').forEach(function(x){
			o = o[x] = o[x] || {};
		});
		return o;
	};
	const ns = namespace("com.ziesemer.myApp");
	
	// Optional:
	ns.namespace = ns;
	
	// Further extend, work with ns from here...
}());

console.log("\"com\":", com);

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


मॉड्यूल पैटर्न मूल रूप से परंपरागत सॉफ्टवेयर इंजीनियरिंग में कक्षाओं के लिए निजी और सार्वजनिक encapsulation दोनों प्रदान करने के लिए एक तरीका के रूप में परिभाषित किया गया था।

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

जावास्क्रिप्ट में, मॉड्यूल पैटर्न का उपयोग कक्षाओं की अवधारणा को इस तरह से अनुकरण करने के लिए किया जाता है कि हम एक ही वस्तु के अंदर सार्वजनिक / निजी विधियों और चर दोनों को शामिल करने में सक्षम हैं, इस प्रकार वैश्विक दायरे से विशेष भागों को संरक्षित करते हैं। इसका परिणाम पृष्ठ पर अतिरिक्त स्क्रिप्ट में परिभाषित अन्य कार्यों के साथ विवादित हमारे फ़ंक्शन नामों की संभावना में कमी है।

var myNamespace = (function () {

  var myPrivateVar, myPrivateMethod;

  // A private counter variable
  myPrivateVar = 0;

  // A private function which logs any arguments
  myPrivateMethod = function( foo ) {
      console.log( foo );
  };

  return {

    // A public variable
    myPublicVar: "foo",

    // A public function utilizing privates
    myPublicFunction: function( bar ) {

      // Increment our private counter
      myPrivateVar++;

      // Call our private method using bar
      myPrivateMethod( bar );

    }
  };

})();

लाभ

मॉड्यूल पैटर्न एक अच्छा विकल्प क्यों है? शुरुआत करने वालों के लिए, कम से कम एक जावास्क्रिप्ट परिप्रेक्ष्य से, वास्तविक encapsulation के विचार से ऑब्जेक्ट उन्मुख पृष्ठभूमि से आने वाले डेवलपर्स के लिए यह बहुत साफ है।

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

नुकसान

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

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

खुलासा मॉड्यूल पैटर्न

अब जब हम मॉड्यूल पैटर्न से थोड़ा अधिक परिचित हैं, तो हम थोड़ा बेहतर संस्करण देखें - क्रिश्चियन हेइलमैन के प्रकटन मॉड्यूल पैटर्न।

प्रकटीकरण मॉड्यूल पैटर्न के बारे में आया क्योंकि हेइलमैन इस तथ्य से निराश थे कि उन्हें मुख्य वस्तु का नाम दोहराया जाना था जब हम एक सार्वजनिक विधि को दूसरे से कॉल करना चाहते थे या सार्वजनिक चरों तक पहुंचना चाहते थे। उन्होंने स्विच करने के लिए मॉड्यूल पैटर्न की आवश्यकता को भी नापसंद किया उन चीजों के लिए शाब्दिक नोटेशन ऑब्जेक्ट करने के लिए जो उन्होंने सार्वजनिक करना चाहते थे।

उनके प्रयासों का नतीजा एक अद्यतन पैटर्न था जहां हम निजी क्षेत्र में हमारे सभी कार्यों और चर को परिभाषित करेंगे और पॉइंटर्स के साथ एक अज्ञात ऑब्जेक्ट को निजी कार्यक्षमता में वापस कर देंगे जिसे हम जनता के रूप में प्रकट करना चाहते थे।

प्रकटन मॉड्यूल पैटर्न का उपयोग कैसे करें इसका एक उदाहरण नीचे पाया जा सकता है

var myRevealingModule = (function () {

        var privateVar = "Ben Cherry",
            publicVar = "Hey there!";

        function privateFunction() {
            console.log( "Name:" + privateVar );
        }

        function publicSetName( strName ) {
            privateVar = strName;
        }

        function publicGetName() {
            privateFunction();
        }


        // Reveal public pointers to
        // private functions and properties

        return {
            setName: publicSetName,
            greeting: publicVar,
            getName: publicGetName
        };

    })();

myRevealingModule.setName( "Paul Kinlan" );

लाभ

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

नुकसान

इस पैटर्न का एक नुकसान यह है कि यदि कोई निजी फ़ंक्शन किसी सार्वजनिक फ़ंक्शन को संदर्भित करता है, तो पैच आवश्यक होने पर सार्वजनिक फ़ंक्शन को ओवरराइड नहीं किया जा सकता है। ऐसा इसलिए है क्योंकि निजी कार्य निजी कार्यान्वयन का संदर्भ जारी रखेगा और पैटर्न केवल सदस्यों के लिए सार्वजनिक सदस्यों पर लागू नहीं होता है।

सार्वजनिक ऑब्जेक्ट सदस्य जो निजी चर का संदर्भ लेते हैं वे उपरोक्त नो-पैच नियम नोट्स के अधीन भी हैं।


यदि आपको निजी दायरे की आवश्यकता है:

var yourNamespace = (function() {

  //Private property
  var publicScope = {};

  //Private property
  var privateProperty = "aaa"; 

  //Public property
  publicScope.publicProperty = "bbb";

  //Public method
  publicScope.publicMethod = function() {
    this.privateMethod();
  };

  //Private method
  function privateMethod() {
    console.log(this.privateProperty);
  }

  //Return only the public parts
  return publicScope;
}());

yourNamespace.publicMethod();

अन्यथा यदि आप कभी भी निजी दायरे का उपयोग नहीं करेंगे:

var yourNamespace = {};

yourNamespace.publicMethod = function() {
    // Do something...
};

yourNamespace.publicMethod2 = function() {
    // Do something...
};

yourNamespace.publicMethod();

यहां बताया गया है कि कैसे स्टोयान स्टीफानोव अपनी जावास्क्रिप्ट पैटर्न पुस्तक में ऐसा करता है जो मुझे बहुत अच्छा लगता है (यह भी दिखाता है कि वह कैसे टिप्पणियां करता है जो स्वत: जेनरेट किए गए एपीआई दस्तावेज़ों की अनुमति देता है, और एक कस्टम ऑब्जेक्ट के प्रोटोटाइप में विधि कैसे जोड़ सकता है):

/**
* My JavaScript application
*
* @module myapp
*/

/** @namespace Namespace for MYAPP classes and functions. */
var MYAPP = MYAPP || {};

/**
* A maths utility
* @namespace MYAPP
* @class math_stuff
*/
MYAPP.math_stuff = {

    /**
    * Sums two numbers
    *
    * @method sum
    * @param {Number} a First number
    * @param {Number} b Second number
    * @return {Number} Sum of the inputs
    */
    sum: function (a, b) {
        return a + b;
    },

    /**
    * Multiplies two numbers
    *
    * @method multi
    * @param {Number} a First number
    * @param {Number} b Second number
    * @return {Number} The inputs multiplied
    */
    multi: function (a, b) {
        return a * b;
    }
};

/**
* Constructs Person objects
* @class Person
* @constructor
* @namespace MYAPP
* @param {String} First name
* @param {String} Last name
*/
MYAPP.Person = function (first, last) {

    /**
    * First name of the Person
    * @property first_name
    * @type String
    */
    this.first_name = first;

    /**
    * Last name of the Person
    * @property last_name
    * @type String
    */
    this.last_name = last;
};

/**
* Return Person's full name
*
* @method getName
* @return {String} First name + last name
*/
MYAPP.Person.prototype.getName = function () {
    return this.first_name + ' ' + this.last_name;
};

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

global_namespace.Define('startpad.base', function(ns) {
    var Other = ns.Import('startpad.other');
    ....
});

लाभ का विवरण मेरे ब्लॉग पोस्ट पर हैं । आप यहां स्रोत कोड ले सकते हैं

लोड ऑर्डर के संबंध में मॉड्यूल के बीच अलगाव है जो मुझे वास्तव में पसंद है। लोड होने से पहले आप बाह्य मॉड्यूल का संदर्भ ले सकते हैं। और कोड उपलब्ध होने पर आपको प्राप्त ऑब्जेक्ट संदर्भ भर दिया जाएगा।


I've written another namespacing library that works a bit more like packages / units do in other languages. It allows you to create a package of JavaScript code and the reference that package from other code:

File hello.js

Package("hello", [], function() {
  function greeting() {
    alert("Hello World!");
  }
  // Expose function greeting to other packages
  Export("greeting", greeting);
});

File Example.js

Package("example", ["hello"], function(greeting) {
  // Greeting is available here
  greeting();  // Alerts: "Hello World!"
});

Only the second file needs to be included in the page. Its dependencies (file hello.js in this example) will automatically be loaded and the objects exported from those dependencies will be used to populate the arguments of the callback function.

You can find the related project in Packages JS .


If using a Makefile you can do this.

// prelude.hjs
billy = new (
    function moduleWrapper () {
    const exports = this;

// postlude.hjs
return exports;
})();

// someinternalfile.js
function bob () { console.log('hi'); }
exports.bob = bob;

// clientfile.js
billy.bob();

I prefer to use a Makefile anyway once I get to about 1000 lines because I can effectively comment out large swaths of code by removing a single line in the makefile. It makes it easy to fiddle with stuff. Also, with this technique the namespace only appears once in the prelude so it's easy to change and you don't have to keep repeating it inside the library code.

A shell script for live development in the browser when using a makefile:

while (true); do make; sleep 1; done

Add this as a make task 'go' and you can 'make go' to keep your build updated as you code.


My habit is to use function myName() as property storage, and then var myName as "method" holder...

Whether this is legitimate enough or not, beat me! I am relying on my PHP logic all the time, and things simply work. : डी

function myObj() {
    this.prop1 = 1;
    this.prop2 = 2;
    this.prop3 = 'string';
}

var myObj = (
 (myObj instanceof Function !== false)
 ? Object.create({

     $props: new myObj(),
     fName1: function() { /* code..  */ },
     fName2: function() { /* code ...*/ }
 })
 : console.log('Object creation failed!')
);

if (this !== that) myObj.fName1(); else myObj.fName2();

You can also do it in a 'vice versa' way to check before object creation which is much better :

function myObj() {
    this.prop1 = 1;
    this.prop2 = 2;
    this.prop3 = 'string';
}

var myObj = (
    (typeof(myObj) !== "function" || myObj instanceof Function === false)
    ? new Boolean()
    : Object.create({
        $props: new myObj(),
        init: function () { return; },
        fName1: function() { /* code..  */ },
        fName2: function() { /* code ...*/ }
    })
);

if (myObj instanceof Boolean) {
    Object.freeze(myObj);
    console.log('myObj failed!');
    debugger;
}
else
    myObj.init();

Reference to this: JavaScript: Creating Object with Object.create()


We can use it independently in this way:

var A = A|| {};
A.B = {};

A.B = {
    itemOne: null,
    itemTwo: null,
};

A.B.itemOne = function () {
    //..
}

A.B.itemTwo = function () {
    //..
}





javascript-namespaces