जावास्क्रिप्ट में स्थैतिक चर


716

मैं जावास्क्रिप्ट में स्थिर चर कैसे बना सकता हूं?


हम "डिसलाइल: कोई नहीं" शैली विशेषता के साथ लेबल या अन्य HTML टैग को परिभाषित कर सकते हैं और इस मान के लिए वैरिएबल मान और इस मान पर कार्रवाई कर सकते हैं। चलो मुश्किल नहीं है।
असगर

मैंने पाया सबसे सरल समाधान: कक्षा में एक स्थिर चर को बिल्कुल भी परिभाषित न करें। जब आप एक स्थिर चर का उपयोग करना चाहते हैं, तो बस इसे वहां परिभाषित करें और फिर, जैसे someFunc = () => { MyClass.myStaticVariable = 1; }। फिर स्थैतिक सदस्य को वापस करने के लिए एक स्थिर विधि बनाएं, जैसे static getStatic() { return MyClass.myStaticVariable; }। तब आप केवल MyClass.getStatic()स्थैतिक डेटा को प्राप्त करने के लिए कक्षा के बाहर से कॉल कर सकते हैं !
Pixel

जवाबों:


863

यदि आप एक क्लास-आधारित, स्टेटिकली टाइप्ड ऑब्जेक्ट-ओरिएंटेड भाषा (जैसे जावा, C ++ या C #) से आते हैं, तो मुझे लगता है कि आप एक "प्रकार" से संबंधित एक वैरिएबल या विधि बनाने की कोशिश कर रहे हैं, लेकिन उदाहरण के लिए नहीं।

एक "शास्त्रीय" दृष्टिकोण का उपयोग करते हुए, निर्माता कार्यों के साथ एक उदाहरण शायद आपको मूल OO जावास्क्रिप्ट की अवधारणाओं को पकड़ने में मदद कर सकता है:

function MyClass () { // constructor function
  var privateVariable = "foo";  // Private variable 

  this.publicVariable = "bar";  // Public variable 

  this.privilegedMethod = function () {  // Public Method
    alert(privateVariable);
  };
}

// Instance method will be available to all instances but only load once in memory 
MyClass.prototype.publicMethod = function () {    
  alert(this.publicVariable);
};

// Static variable shared by all instances
MyClass.staticProperty = "baz";

var myInstance = new MyClass();

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

अद्यतन: ES6 ने कीवर्ड के माध्यम से कक्षाएं घोषित करने की क्षमता पेश की class। यह मौजूदा प्रोटोटाइप-आधारित विरासत के ऊपर सिंटेक्स चीनी है।

staticकीवर्ड आप आसानी से एक कक्षा में स्थिर गुणों या तरीकों को परिभाषित करने की अनुमति देता है।

आइए ES6 कक्षाओं के साथ लागू किया गया उपरोक्त उदाहरण देखें:

class MyClass {
  // class constructor, equivalent to
  // the function body of a constructor
  constructor() {
    const privateVariable = 'private value'; // Private variable at the constructor scope
    this.publicVariable = 'public value'; // Public property

    this.privilegedMethod = function() {
      // Public Method with access to the constructor scope variables
      console.log(privateVariable);
    };
  }

  // Prototype methods:
  publicMethod() {
    console.log(this.publicVariable);
  }

  // Static properties shared by all instances
  static staticProperty = 'static value';

  static staticMethod() {
    console.log(this.staticProperty);
  }
}

// We can add properties to the class prototype
MyClass.prototype.additionalMethod = function() {
  console.log(this.publicVariable);
};

var myInstance = new MyClass();
myInstance.publicMethod();       // "public value"
myInstance.additionalMethod(); // "public value"
myInstance.privilegedMethod(); // "private value"
MyClass.staticMethod();             // "static value"


5
संभवतः privilegedMethodOO में एक निजी विधि के बराबर नहीं है क्योंकि ऐसा लगता है कि इसे MyClass के उदाहरण पर कहा जा सकता है? क्या आपका मतलब है कि यह विशेषाधिकार प्राप्त है क्योंकि यह एक्सेस कर सकता है privateVariable?
प्रात

3
this.constructor"उदाहरण के तरीकों" से स्थिर चर तक पहुंचने के लिए उपयोग नहीं किया जा सकता है? यदि हाँ, तो यह जवाब में जोड़ने लायक है।
सिरो सेंटिल्ली 冠状 iro iro i 法轮功 '

1
आप अपने उदाहरण में स्थिर कार्यों का भी उल्लेख कर सकते हैं ।
डेविड रोड्रिग्स

18
नमस्ते, मुझे यकीन नहीं है कि मैं इस लाइन से सहमत हूं। सभी उदाहरण 'MyClass.staticProperty = "baz"; जैसा कि मेरे पास है कि आप 'myInstance.staticProperty' से baz पा सकते हैं, जो निश्चित रूप से आप नहीं कर सकते।
फुलस्टैक्लाइफ़

5
शायद इसे पढ़ना चाहिए MyClass.prototype.staticProperty = "baz";या OO सिद्धांतों के लिए और भी अधिक सही होना चाहिए स्थैतिक संपत्ति को वास्तव में एक अनाम फ़ंक्शन के रूप में परिभाषित किया जाना चाहिए MyClass.prototype.staticProperty = function () {return staticVar;}और ताकि सभी उदाहरण एक एकल चर तक पहुंच सकें, जिसे एक सेटर के साथ भी बदला जा सकता है।
लिंडसेमेवियन

535

आप इस तथ्य का लाभ उठा सकते हैं कि जेएस फ़ंक्शन भी ऑब्जेक्ट हैं - जिसका अर्थ है कि उनके पास गुण हो सकते हैं।

उदाहरण के लिए, (अब गायब हो गया) लेख पर दिए गए उदाहरण को उद्धृत करते हुए जावास्क्रिप्ट में स्थैतिक चर :

function countMyself() {
    // Check to see if the counter has been initialized
    if ( typeof countMyself.counter == 'undefined' ) {
        // It has not... perform the initialization
        countMyself.counter = 0;
    }

    // Do something stupid to indicate the value
    alert(++countMyself.counter);
}

यदि आप उस फ़ंक्शन को कई बार कॉल करते हैं, तो आप देखेंगे कि काउंटर को बढ़ाया जा रहा है।

और यह शायद एक वैश्विक चर के साथ वैश्विक नाम स्थान को विचलित करने की तुलना में बहुत बेहतर समाधान है।


और यहां एक और संभव समाधान है, जो एक क्लोजर पर आधारित है: जावास्क्रिप्ट में स्थैतिक चर का उपयोग करने की चाल :

var uniqueID = (function() {
   var id = 0; // This is the private persistent value
   // The outer function returns a nested function that has access
   // to the persistent value.  It is this nested function we're storing
   // in the variable uniqueID above.
   return function() { return id++; };  // Return and increment
})(); // Invoke the outer function after defining it.

जो आपको एक ही तरह का परिणाम देता है - सिवाय, इस बार, बढ़ा हुआ मूल्य प्रदर्शित होने के बजाय वापस कर दिया जाता है।


50
एक शॉर्टकट के रूप में, आप बस कर सकते हैं countMyself.counter = countMyself.counter || initial_value;यदि स्थिर चर कभी भी गलत नहीं होगा (झूठा, 0, अशक्त या खाली स्ट्रिंग)
किप

3
थोड़ा छोटा और स्पष्ट: (फ़ंक्शन () {var id = 0; function uniqueID () {रिटर्न आईडी ++;};}) ();
टॉम रॉबिन्सन

3
फ़ायरफ़ॉक्स में क्लास की तुलना में काउंटर इन क्लोज़र बहुत तेज़ है। jsperf.com/static-counter-in-class-vs-in-closure
Sony Santos

चेकों के ===लिए उपयोग करें typeofऔर आपको कुछ अजीब तरह की चोट लग जाएगी।
dewd

@SonySantos आपका परीक्षण फ़ायरफ़ॉक्स 40 के लिए विपरीत दिखाता है
bartolo-otrit

96

आप इसे IIFE के माध्यम से करते हैं (तुरंत फंक्शन एक्सप्रेशन):

var incr = (function () {
    var i = 1;

    return function () {
        return i++;
    }
})();

incr(); // returns 1
incr(); // returns 2

21
मैं कहूंगा कि यह जावास्क्रिप्ट में करने के लिए सबसे मुहावरेदार तरीका है। बहुत बुरा यह अन्य तरीकों के लिए धन्यवाद बहुत अधिक upvotes नहीं मिलता है जो शायद उन लोगों के लिए अधिक स्वादिष्ट हैं जो अन्य भाषाओं से आते हैं।

1
मैं केवल 'IIFE' के बजाय 'क्लोजर' का उपयोग करके पुनःप्रयास करूँगा।
zendka

39

आप "स्थिर" चर को संग्रहीत करने के लिए तर्कों का उपयोग कर सकते हैं। (यह अनाम फ़ंक्शन में भी उपयोगी है):

function () {
  arguments.callee.myStaticVar = arguments.callee.myStaticVar || 1;
  arguments.callee.myStaticVar++;
  alert(arguments.callee.myStaticVar);
}

3
जहां तक ​​मैं समझ सकता हूं, इस पद्धति में पास्कल मार्टिन के तरीके से एक (केवल एक?) लाभ है: आप इसे गुमनाम कार्यों पर उपयोग कर सकते हैं। इसका एक उदाहरण बहुत अच्छा होगा
डैन

27
arguments.calleeपदावनत किया गया है।
Quolonel प्रश्न

मैं हर समय जेएस का बहुत उपहास करता हूं, लेकिन calleeएक अच्छी बात है। मुझे आश्चर्य है कि हैक ने उन्हें इस पदावनत करने का निर्णय क्यों लिया ...: |
user2173353

34

मैंने कुछ ऐसे ही उत्तर देखे हैं, लेकिन मैं यह उल्लेख करना चाहूंगा कि यह पोस्ट इसे सबसे अच्छा बताती है, इसलिए मैं इसे आपके साथ साझा करना चाहूंगा।

यहां से कुछ कोड लिया गया है, जिसे मैंने एक पूर्ण उदाहरण प्राप्त करने के लिए संशोधित किया है, जो उम्मीद है कि समुदाय को लाभ देता है क्योंकि इसे कक्षाओं के लिए डिज़ाइन टेम्पलेट के रूप में उपयोग किया जा सकता है।

यह आपके प्रश्न का उत्तर भी देता है:

function Podcast() {

    // private variables
    var _somePrivateVariable = 123;

    // object properties (read/write)
    this.title = 'Astronomy Cast';
    this.description = 'A fact-based journey through the galaxy.';
    this.link = 'http://www.astronomycast.com';

    // for read access to _somePrivateVariable via immutableProp 
    this.immutableProp = function() {
        return _somePrivateVariable;
    }

    // object function
    this.toString = function() {
       return 'Title: ' + this.title;
    }
};

// static property
Podcast.FILE_EXTENSION = 'mp3';
// static function
Podcast.download = function(podcast) {
    console.log('Downloading ' + podcast + ' ...');
};

उस उदाहरण को देखते हुए, आप स्थैतिक गुणों / फ़ंक्शन को निम्नानुसार एक्सेस कर सकते हैं:

// access static properties/functions
console.log(Podcast.FILE_EXTENSION);   // 'mp3'
Podcast.download('Astronomy cast');    // 'Downloading Astronomy cast ...'

और वस्तु के गुण / कार्य जैसे:

// access object properties/functions
var podcast = new Podcast();
podcast.title = 'The Simpsons';
console.log(podcast.toString());       // Title: The Simpsons
console.log(podcast.immutableProp());  // 123

ध्यान दें कि पॉडकास्ट.म्यूटेबलपेप () में, हमारे पास एक क्लोजर है : फ़ंक्शन के अंदर _somePStreetVariable का संदर्भ रखा गया है।

आप गेटर्स और सेटर को भी परिभाषित कर सकते हैं । इस कोड स्निपेट पर एक नज़र डालें (जहां dऑब्जेक्ट का प्रोटोटाइप है जिसके लिए आप एक संपत्ति घोषित करना चाहते हैं, yएक निजी चर है जो कंस्ट्रक्टर के बाहर दिखाई नहीं देता है):

// getters and setters
var d = Date.prototype;
Object.defineProperty(d, "year", {
    get: function() {return this.getFullYear() },
    set: function(y) { this.setFullYear(y) }
});

यह संपत्ति d.yearको कार्यों getऔर setकार्यों के माध्यम से परिभाषित करता है - यदि आप निर्दिष्ट नहीं करते हैं set, तो संपत्ति केवल पढ़ने योग्य है और इसे संशोधित नहीं किया जा सकता है (ध्यान रखें कि यदि आप इसे सेट करने का प्रयास करते हैं तो आपको कोई त्रुटि नहीं मिलेगी, लेकिन इसका कोई प्रभाव नहीं है)। प्रत्येक संपत्ति में विशेषताएँ हैं writable, configurable(घोषणा के बाद बदलने की अनुमति) और enumerable(गणनाकर्ता के रूप में उपयोग करने की अनुमति), जो कि डिफ़ॉल्ट रूप से हैं false। आप उन्हें defineProperty3 पैरामीटर में सेट कर सकते हैं , जैसे enumerable: true

क्या यह भी मान्य है यह वाक्यविन्यास है:

// getters and setters - alternative syntax
var obj = { a: 7, 
            get b() {return this.a + 1;}, 
            set c(x) {this.a = x / 2}
        };

जो एक पठनीय / लिखने योग्य संपत्ति a, एक पढ़ने योग्य संपत्ति bऔर एक केवल लिखने योग्य संपत्ति को परिभाषित करता है c, जिसके माध्यम से संपत्ति aतक पहुँचा जा सकता है।

उपयोग:

console.log(obj.a); console.log(obj.b); // output: 7, 8
obj.c=40;
console.log(obj.a); console.log(obj.b); // output: 20, 21

टिप्पणियाँ:

यदि आप newकीवर्ड को भूल गए हैं, तो अप्रत्याशित व्यवहार से बचने के लिए , मेरा सुझाव है कि आप फ़ंक्शन में निम्नलिखित जोड़ें Podcast:

// instantiation helper
function Podcast() {
    if(false === (this instanceof Podcast)) {
        return new Podcast();
    }
// [... same as above ...]
};

अब निम्नलिखित दोनों इंस्टेंटेशन उम्मीद के मुताबिक काम करेंगे:

var podcast = new Podcast(); // normal usage, still allowed
var podcast = Podcast();     // you can omit the new keyword because of the helper

'नया' कथन एक नई वस्तु बनाता है और सभी गुणों और विधियों को कॉपी करता है, अर्थात

var a=new Podcast();
var b=new Podcast();
a.title="a"; b.title="An "+b.title;
console.log(a.title); // "a"
console.log(b.title); // "An Astronomy Cast"

यह भी ध्यान दें, कि कुछ स्थितियों returnमें निर्माण कार्य में कथन का उपयोग करने के लिए उपयोगी हो सकता है Podcastएक कस्टम ऑब्जेक्ट को संरक्षित करने वाले कार्यों को वापस करने के लिए जो वर्ग आंतरिक रूप से निर्भर करता है लेकिन जिसे उजागर करने की आवश्यकता होती है। इसे आगे लेख श्रृंखला के अध्याय 2 (ऑब्जेक्ट्स) में समझाया गया है।

आप कह सकते हैं कि aऔर से bविरासत में मिला है Podcast। अब, क्या होगा यदि आप पॉडकास्ट के लिए एक विधि जोड़ना चाहते हैं जो उन सभी पर लागू होता है aऔर बाद bमें निर्जन किया गया है? इस मामले में, .prototypeनिम्नानुसार उपयोग करें :

Podcast.prototype.titleAndLink = function() {
    return this.title + " [" + this.link + "]";
};

अब फोन aऔर bफिर से:

console.log(a.titleAndLink()); // "a [http://www.astronomycast.com]"
console.log(b.titleAndLink()); // "An Astronomy Cast [http://www.astronomycast.com]"

आप यहां प्रोटोटाइप के बारे में अधिक जानकारी पा सकते हैं । यदि आप अधिक उत्तराधिकार करना चाहते हैं, तो मेरा सुझाव है कि इस पर गौर करें


ऊपर मैंने जिन लेख श्रृंखलाओं का उल्लेख किया है , उन्हें पढ़ने की अत्यधिक अनुशंसा की जाती है, उनमें निम्नलिखित विषय भी शामिल हैं:

  1. कार्य
  2. वस्तुओं
  3. प्रोटोटाइप
  4. कंस्ट्रक्टर कार्यों पर नया लागू करना
  5. उत्थापन
  6. स्वचालित अर्धविराम सम्मिलन
  7. स्थैतिक गुण और तरीके

ध्यान दें कि स्वचालित अर्धविराम प्रविष्टि "सुविधा" जावास्क्रिप्ट (जैसा कि 6. में उल्लेख किया गया है) अक्सर आपके कोड में अजीब मुद्दे पैदा करने के लिए जिम्मेदार होती है। इसलिए, मैं इसे एक फीचर के रूप में बग के रूप में मानूंगा।

आप अधिक पढ़ने के लिए चाहते हैं, तो यहाँ एक काफी रोचक है MSDN लेख इन विषयों के बारे, उनमें से कुछ वहाँ प्रदान में और अधिक विवरण का वर्णन किया।

जैसा कि पढ़ने के लिए दिलचस्प है (ऊपर वर्णित विषयों को भी कवर करना) एमडीएन जावास्क्रिप्ट गाइड के वे लेख हैं :

यदि आप जानना चाहते हैं कि जावास्क्रिप्ट में c # outपैरामीटर (जैसे DateTime.TryParse(str, out result)) का अनुकरण कैसे करें , तो आप यहां नमूना कोड पा सकते हैं


आप में से जो IE के साथ काम कर रहे हैं (जिसमें जावास्क्रिप्ट के लिए कोई कंसोल नहीं है जब तक कि आप डेवलपर टूल का उपयोग करके F12और कंसोल टैब को नहीं खोलते हैं) निम्नलिखित स्निपेट को उपयोगी पा सकते हैं। यह आपको console.log(msg);ऊपर दिए गए उदाहरणों में उपयोग करने की अनुमति देता है। इसे Podcastफंक्शन से पहले डालें ।

आपकी सुविधा के लिए, यहाँ एक पूर्ण एकल कोड स्निपेट में ऊपर दिया गया कोड है:


टिप्पणियाँ:

  • सामान्य रूप से जावास्क्रिप्ट प्रोग्रामिंग के बारे में कुछ अच्छे सुझाव, संकेत और सिफारिशें आप यहां (जावास्क्रिप्ट सर्वोत्तम प्रथाओं) और वहां ('var' बनाम 'लेट') पा सकते हैं । यह भी सिफारिश की है कि इस लेख के बारे में निहित टाइपकास्ट (जबरदस्ती) है

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

  • जावास्क्रिप्ट में स्थानीय चर, कार्यों आदि के एनकैप्सुलेशन को प्राप्त करने के लिए , मैं निम्नलिखित पैटर्न का उपयोग करने का सुझाव देता हूं (JQuery एक ही तकनीक का उपयोग करता है):

<html>
<head></head>
<body><script>
    'use strict';
    // module pattern (self invoked function)
    const myModule = (function(context) { 
    // to allow replacement of the function, use 'var' otherwise keep 'const'

      // put variables and function with local module scope here:
      var print = function(str) {
        if (str !== undefined) context.document.write(str);
        context.document.write("<br/><br/>");
        return;
      }
      // ... more variables ...

      // main method
      var _main = function(title) {

        if (title !== undefined) print(title);
        print("<b>last modified:&nbsp;</b>" + context.document.lastModified + "<br/>");        
        // ... more code ...
      }

      // public methods
      return {
        Main: _main
        // ... more public methods, properties ...
      };

    })(this);

    // use module
    myModule.Main("<b>Module demo</b>");
</script></body>
</html>

बेशक, आप कर सकते हैं - और चाहिए - एक अलग *.jsफ़ाइल में स्क्रिप्ट कोड ; यह सिर्फ उदाहरण को छोटा रखने के लिए इनलाइन लिखा है।

सेल्फ-इनवोकिंग फ़ंक्शन (जिसे IIFE = तत्काल इनवॉइस फंक्शन एक्सप्रेशन के रूप में भी जाना जाता है) को यहां और अधिक विस्तार से वर्णित किया गया है


28
function Person(){
  if(Person.count == undefined){
    Person.count = 1;
  }
  else{
    Person.count ++;
  }
  console.log(Person.count);
}

var p1 = new Person();
var p2 = new Person();
var p3 = new Person();

28

अद्यतन उत्तर:

में ECMAScript 6 , आप का उपयोग कर स्थिर कार्यों बना सकते हैं staticकीवर्ड:

class Foo {

  static bar() {return 'I am static.'}

}

//`bar` is a property of the class
Foo.bar() // returns 'I am static.'

//`bar` is not a property of instances of the class
var foo = new Foo()
foo.bar() //-> throws TypeError

ES6 कक्षाएं स्टैटिक्स के लिए किसी भी नए शब्दार्थ का परिचय नहीं देती हैं। आप इस तरह ES5 में एक ही काम कर सकते हैं:

//constructor
var Foo = function() {}

Foo.bar = function() {
    return 'I am static.'
}

Foo.bar() // returns 'I am static.'

var foo = new Foo()
foo.bar() // throws TypeError

आप Fooजावास्क्रिप्ट कार्यों में ऑब्जेक्ट होने के कारण आप किसी प्रॉपर्टी को असाइन कर सकते हैं ।


Foo.bar;फ़ंक्शन को इसे सौंपा गया है, न कि स्ट्रिंग फ़ंक्शन द्वारा लौटाया गया जैसा कि आपकी टिप्पणी का तात्पर्य है।

क्या आप उन दोनों उदाहरणों में स्थैतिक मान सेट (ओवरराइट) करने के बारे में कुछ जानकारी जोड़ सकते हैं?
विल्ट

1
@ दोनों मामलों में, "स्थिर" संपत्ति फ़ंक्शन पर एक संपत्ति है, इसलिए आप इसे सेट करते हैं और इसे वैसे ही अधिलेखित कर देते हैं, जैसे आप जावास्क्रिप्ट में किसी अन्य संपत्ति में हैं। दोनों ही मामलों में, आप सेट कर सकते हैं barकी संपत्ति Fooके लिए 3: यह पसंदFoo.bar = 3;
मैक्स Heiber


16

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

(function () {
    var name = '';
    Person = function (value) {
        name = value;
    };
    Person.prototype.getName = function () {
        return name;
    };
    Person.prototype.setName = function (value) {
        name = value;
    };
}());
var person1 = new Person('Nate');
console.log(person1.getName()); // Nate
person1.setName('James');
console.log(person1.getName()); // James
person1.name = 'Mark';
console.log(person1.name); // Mark
console.log(person1.getName()); // James
var person2 = new Person('Danielle');
console.log(person1.getName()); // Danielle
console.log(person2.getName()); // Danielle

Personइस उदाहरण में निर्माता के रूप में करते हैं निजी चर नाम की पहुंच है, getName()और setName()तरीकों। इस पैटर्न का उपयोग करते हुए, नाम चर स्थिर हो जाता है और सभी उदाहरणों के बीच उपयोग किया जाएगा। इसका मतलब है कि setName()एक उदाहरण पर कॉल करना अन्य सभी उदाहरणों को प्रभावित करता है। setName()किसी नए Personइंस्टेंस को कॉल करना या बनाना एक नया मान नाम चर सेट करता है। यह सभी मानों को समान मान वापस करने का कारण बनता है।


कंस्ट्रक्टर + प्रोटोटाइप (हाइब्रिड) दिखता है
गणेश कुमार

2
यह व्यक्ति के ऑब्जेक्ट को वैश्विक नामस्थान में रखता है। एक समाधान नहीं जो मैं सुझाऊँगा।
घोला १

मुझे नहीं लगता कि यह एक सच्चा स्थिर वैरिएबल है क्योंकि यह प्रत्येक नई वस्तु के साथ अलग-अलग रूप से त्वरित है। मूल ऑब्जेक्ट से विरासत में मिली सभी वस्तुओं पर एक स्थिर वस्तु सुसंगत होनी चाहिए?
लिंडसेमेवैन

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

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

15

यदि आप नए वर्ग के सिंटैक्स का उपयोग कर रहे हैं तो अब आप निम्नलिखित कार्य कर सकते हैं:

    class MyClass {
      static get myStaticVariable() {
        return "some static variable";
      }
    }

    console.log(MyClass.myStaticVariable);

    aMyClass = new MyClass();
    console.log(aMyClass.myStaticVariable, "is undefined");

यह प्रभावी रूप से जावास्क्रिप्ट में एक स्थिर चर बनाता है।


स्थैतिक उपयोगिता वर्गों के निर्माण के समय यह उपयोगी है!
इंडोलिंग

1
लेकिन अब सवाल यह है कि आप एक मूल्य कैसे बनाए रखते हैं और एक सेटर के साथ इसमें बदलाव की अनुमति देते हैं। MyClassवर्ग निर्माण के बाहर परिभाषित करने पर एक संपत्ति या एक संपत्ति की आवश्यकता होगी ।
त्रिनोट


8

यदि आप अपने आवेदन में स्थिरांक बनाने के लिए स्थैतिक चर घोषित करना चाहते हैं तो मुझे सबसे सरल दृष्टिकोण के रूप में निम्नलिखित पाया गया

ColorConstants = (function()
{
    var obj = {};
    obj.RED = 'red';
    obj.GREEN = 'green';
    obj.BLUE = 'blue';
    obj.ALL = [obj.RED, obj.GREEN, obj.BLUE];
    return obj;
})();

//Example usage.
var redColor = ColorConstants.RED;

8

बारे में classECMAScript 2015 तक शुरू की अन्य उत्तर पूरी तरह से स्पष्ट नहीं कर रहे हैं।

यहां एक उदाहरण दिखाया गया है कि किस तरह से स्थिर संस्करण बनाया staticVarजा सकता है ClassNamevarsynthax:

class MyClass {
    constructor(val) {
        this.instanceVar = val;
        MyClass.staticVar = 10;
    }
}

var class1 = new MyClass(1);
console.log(class1.instanceVar);      // 1
console.log(class1.constructor.staticVar); // 10

// New instance of MyClass with another value
var class2 = new MyClass(3);
console.log(class1.instanceVar);      // 1
console.log(class2.instanceVar);      // 3

स्थिर वैरिएबल का उपयोग करने के लिए हम उस .constructorसंपत्ति का उपयोग करते हैं जो क्लास के लिए बनाई गई ऑब्जेक्ट कंस्ट्रक्टर फ़ंक्शन का संदर्भ देता है। हम इसे दो निर्मित उदाहरणों पर कॉल कर सकते हैं:

MyClass.staticVar = 11;
console.log(class1.constructor.staticVar); // 11
console.log(class2.constructor.staticVar); // 11 <-- yes it's static! :)

MyClass.staticVar = 12;
console.log(class1.constructor.staticVar); // 12
console.log(class2.constructor.staticVar); // 12

7

इसी तरह के अन्य उत्तर भी हैं, लेकिन उनमें से कोई भी मुझे काफी पसंद नहीं आया। यहाँ मैंने क्या किया:

var nextCounter = (function () {
  var counter = 0;
  return function() {
    var temp = counter;
    counter += 1;
    return temp;
  };
})();

7

बाकी के अलावा, वर्तमान में ECMA प्रस्तावों पर एक मसौदा ( चरण -2 प्रस्ताव ) है जो परिचय देता हैstatic जो कक्षाओं में सार्वजनिक क्षेत्रों का देता है। ( निजी क्षेत्रों पर विचार किया गया )

प्रस्ताव से उदाहरण का उपयोग, प्रस्तावित static सिंटैक्स इस तरह दिखाई देगा:

class CustomDate {
  // ...
  static epoch = new CustomDate(0);
}

और निम्नलिखित के बराबर होना चाहिए जो अन्य लोगों ने उजागर किया है:

class CustomDate {
  // ...
}
CustomDate.epoch = new CustomDate(0);

फिर आप इसके द्वारा एक्सेस कर सकते हैं CustomDate.epoch

आप नए प्रस्ताव पर नज़र रख सकते हैं proposal-static-class-features


वर्तमान में, बैबल ट्रांसफॉर्म क्लास प्रॉपर्टीज प्लगइन के साथ इस सुविधा का समर्थन करता है जिसका आप उपयोग कर सकते हैं। इसके अतिरिक्त, हालांकि अभी भी प्रगति में है, V8इसे लागू कर रहा है


6

आप इस तरह जावास्क्रिप्ट में एक स्थिर चर बना सकते हैं। यहाँ countस्थिर चर है।

var Person = function(name) {
  this.name = name;
  // first time Person.count is undefined, so it is initialized with 1
  // next time the function is called, the value of count is incremented by 1
  Person.count = Person.count ? Person.count + 1 : 1;
}

var p1 = new Person('User p1');
console.log(p1.constructor.count);   // prints 1
var p2 = new Person('User p2');
console.log(p2.constructor.count);   // prints 2

आप Personफ़ंक्शन, या किसी भी उदाहरण का उपयोग करके स्थिर चर को मान प्रदान कर सकते हैं :

// set static variable using instance of Person
p1.constructor.count = 10;         // this change is seen in all the instances of Person
console.log(p2.constructor.count); // prints 10

// set static variable using Person
Person.count = 20;
console.log(p1.constructor.count); // prints 20

यह स्थिर चर घोषित करने और इसे जावास्क्रिप्ट में एक्सेस करने के लिए एक अच्छा तरीका है।
अरुणध्वज IIITH

5

यदि आप एक वैश्विक स्थिर वैरिएबल बनाना चाहते हैं:

var my_id = 123;

चर को नीचे से बदलें:

Object.defineProperty(window, 'my_id', {
    get: function() {
            return 123;
        },
    configurable : false,
    enumerable : false
});

4

जावास्क्रिप्ट में स्थैतिक चर के लिए निकटतम चीज एक वैश्विक चर है - यह केवल एक चर है जो किसी फ़ंक्शन या ऑब्जेक्ट शाब्दिक के दायरे से बाहर घोषित किया जाता है:

var thisIsGlobal = 1;

function foo() {
    var thisIsNot = 2;
}

दूसरी चीज जो आप कर सकते हैं, वह इस तरह से वस्तु के शाब्दिक के अंदर वैश्विक चर को स्टोर करना होगा:

var foo = { bar : 1 }

और फिर इस तरह से वैरिएबल्स का उपयोग करें foo.bar:।


इसने कई फाइलों को अपलोड करने में मेरी मदद की ..... var foo = {counter: 1}; कार्य अधिक करें () {fileName = "फ़ाइल" + foo.counter; foo.counter = foo.counter + 1;
veer7

4

यहां सभी वर्ग अवधारणाओं को संक्षेपित करने के लिए, इसका परीक्षण करें:

var Test = function() {
  // "super private" variable, accessible only here in constructor. There are no real private variables
  //if as 'private' we intend variables accessible only by the class that defines the member and NOT by child classes
  var test_var = "super private";

  //the only way to access the "super private" test_var is from here
  this.privileged = function(){
    console.log(test_var);
  }();

  Test.test_var = 'protected';//protected variable: accessible only form inherited methods (prototype) AND child/inherited classes

  this.init();
};//end constructor

Test.test_var = "static";//static variable: accessible everywhere (I mean, even out of prototype, see domready below)

Test.prototype = {

 init:function(){
   console.log('in',Test.test_var);
 }

};//end prototype/class


//for example:
$(document).ready(function() {

 console.log('out',Test.test_var);

 var Jake = function(){}

 Jake.prototype = new Test();

 Jake.prototype.test = function(){
   console.log('jake', Test.test_var);
 }

 var jake = new Jake();

 jake.test();//output: "protected"

});//end domready

खैर, इन बातों में सर्वोत्तम प्रथाओं पर एक नज़र डालने के लिए, यह देखने के लिए कि कॉफ़ीस्क्रिप्ट इन अवधारणाओं का अनुवाद कैसे करता है।

#this is coffeescript
class Test
 #static
 @prop = "static"

 #instance
 constructor:(prop) ->
   @prop = prop
   console.log(@prop)

 t = new Test('inst_prop');

 console.log(Test.prop);


//this is how the above is translated in plain js by the CS compiler
  Test = (function() {
    Test.prop = "static";

    function Test(prop) {
     this.prop = prop;
     console.log(this.prop);
    }

    return Test;

  })();

  t = new Test('inst_prop');

  console.log(Test.prop);

4

जावास्क्रिप्ट चर में डिफ़ॉल्ट रूप से स्थिर हैं । उदाहरण :

var x = 0;

function draw() {
    alert(x); //
    x+=1;
}

setInterval(draw, 1000);

X का मान 1 प्रत्येक 1000 मिलीसेकेंड
बढ़ जाता है। यह 1,2,3 को आगे मुद्रित करेगा


2
वह अलग मामला है। आपका उदाहरण scopes के बारे में है।
चैलेट

4

एक और दृष्टिकोण है, जिसने इस धागे को ब्राउज़ करने के बाद मेरी आवश्यकताओं को हल किया है। यह ठीक उसी पर निर्भर करता है जो आप "स्टैटिक वैरिएबल" से हासिल करना चाहते हैं।

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

यह शीर्ष स्तर के वैश्विक चर, यानी Window.myglobal के दायरे, जीवनकाल, शब्दार्थ, गतिकी आदि के साथ सभी परेशानियों से बचा जाता है। पता नहीं यह कितना कुशल है, लेकिन यह मामूली मात्रा में डेटा के लिए महत्वपूर्ण नहीं है, मामूली दरों पर पहुँचा जा सकता है।

आसानी से "sessionStorage.mydata = something" के रूप में एक्सेस किया गया और समान रूप से पुनर्प्राप्त किया गया। "जावास्क्रिप्ट: द डेफिनिटिव गाइड, सिक्स्थ एडिशन", डेविड फ्लैगन, आईएसबीएन: 978-0-596-80552-4, अध्याय 20, धारा 20.1 देखें। यह एक पीडीएफ के रूप में सरल खोज, या आपके ओ'रिली सफारिबूक सदस्यता (सोने में अपने वजन के लायक) के रूप में आसानी से डाउनलोड करने योग्य है।


2

फ़ंक्शन / कक्षाएं अपने ऑब्जेक्ट स्कोप के लिए केवल एकल कंस्ट्रक्टर को अनुमति देती हैं। Function Hoisting, declarations & expressions

  • फंक्शन कन्स्ट्रक्टर के साथ बनाए गए कार्य उनके निर्माण संदर्भों के लिए नज़दीकियाँ पैदा नहीं करते हैं; वे हमेशा वैश्विक दायरे में निर्मित होते हैं।

      var functionClass = function ( ) {
            var currentClass = Shape;
            _inherits(currentClass, superClass);
            function functionClass() { superClass.call(this); // Linking with SuperClass Constructor.
                // Instance Variables list.
                this.id = id;   return this;
            }
        }(SuperClass)

बंद - क्लोजर की प्रतियां संरक्षित डेटा के साथ कार्य करती हैं।

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

      function closureFun( args ) {
            // Local variable that ends up within closure
            var num = args;
            num++;
            return function() { console.log(num); }
        }
        var closure1 = closureFun( 5 );
        var closure2 = closureFun( 777 );
        closure1(); // 5
        closure2(); // 777
        closure2(); // 778
        closure1(); // 6

ES5 फंक्शन क्लासेस : का उपयोग करता हैES5 Object.defineProperty (O, P, Attributes)

Object.defineProperty () विधि एक वस्तु पर एक वस्तु पर सीधे एक नई संपत्ति को परिभाषित करता है, या संशोधित किसी मौजूदा प्रॉपर्टी, और वस्तु देता है।

`` का उपयोग करके कुछ तरीके बनाए , ताकि हर एक बार फ़ंक्शन कक्षाओं को आसानी से समझ सकें।

'use strict';
var Shape = function ( superClass ) {
    var currentClass = Shape;
    _inherits(currentClass, superClass); // Prototype Chain - Extends

    function Shape(id) { superClass.call(this); // Linking with SuperClass Constructor.
        // Instance Variables list.
        this.id = id;   return this;
    }
    var staticVariablesJOSN = { "parent_S_V" : 777 };
    staticVariable( currentClass, staticVariablesJOSN );

    // Setters, Getters, instanceMethods. [{}, {}];
    var instanceFunctions = [
        {
            key: 'uniqueID',
            get: function get() { return this.id; },
            set: function set(changeVal) { this.id = changeVal; }
        }
    ];
    instanceMethods( currentClass, instanceFunctions );

    return currentClass;
}(Object);

var Rectangle = function ( superClass ) {
    var currentClass = Rectangle;

    _inherits(currentClass, superClass); // Prototype Chain - Extends

    function Rectangle(id, width, height) { superClass.call(this, id); // Linking with SuperClass Constructor.

        this.width = width;
        this.height = height;   return this;
    }

    var staticVariablesJOSN = { "_staticVar" : 77777 };
    staticVariable( currentClass, staticVariablesJOSN );

    var staticFunctions = [
        {
            key: 'println',
            value: function println() { console.log('Static Method'); }
        }
    ];
    staticMethods(currentClass, staticFunctions);

    var instanceFunctions = [
        {
            key: 'setStaticVar',
            value: function setStaticVar(staticVal) {
                currentClass.parent_S_V = staticVal;
                console.log('SET Instance Method Parent Class Static Value : ', currentClass.parent_S_V);
            }
        }, {
            key: 'getStaticVar',
            value: function getStaticVar() {
                console.log('GET Instance Method Parent Class Static Value : ', currentClass.parent_S_V);
                return currentClass.parent_S_V;
            }
        }, {
            key: 'area',
            get: function get() {
                console.log('Area : ', this.width * this.height);
                return this.width * this.height;
                }
        }, {
            key: 'globalValue',
            get: function get() {
                console.log('GET ID : ', currentClass._staticVar);
                return currentClass._staticVar;
            },
            set: function set(value) {
                currentClass._staticVar = value;
                console.log('SET ID : ', currentClass._staticVar);
            }
        }
    ];
    instanceMethods( currentClass, instanceFunctions );

    return currentClass;
}(Shape);

// ===== ES5 Class Conversion Supported Functions =====
function defineProperties(target, props) {
    console.log(target, ' : ', props);
    for (var i = 0; i < props.length; i++) {
        var descriptor = props[i];
        descriptor.enumerable = descriptor.enumerable || false;
        descriptor.configurable = true;
        if ("value" in descriptor) descriptor.writable = true;
        Object.defineProperty(target, descriptor.key, descriptor);
    }
}
function staticMethods( currentClass, staticProps ) {
    defineProperties(currentClass, staticProps);
};
function instanceMethods( currentClass, protoProps ) {
    defineProperties(currentClass.prototype, protoProps);
};
function staticVariable( currentClass, staticVariales ) {
    // Get Key Set and get its corresponding value.
    // currentClass.key = value;
    for( var prop in staticVariales ) {
        console.log('Keys : Values');
        if( staticVariales.hasOwnProperty( prop ) ) {
            console.log(prop, ' : ', staticVariales[ prop ] );
            currentClass[ prop ] = staticVariales[ prop ];
        }
    }
};
function _inherits(subClass, superClass) {
    console.log( subClass, ' : extends : ', superClass );
    if (typeof superClass !== "function" && superClass !== null) {
        throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
    }
    subClass.prototype = Object.create(superClass && superClass.prototype, 
            { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } });
    if (superClass)
        Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
}

नीचे दिए गए कोड स्निपेट को प्रत्येक उदाहरण के बारे में परीक्षण करना है, उदाहरण के सदस्यों और सामान्य स्थैतिक सदस्यों की अपनी प्रति है।

var objTest = new Rectangle('Yash_777', 8, 7);
console.dir(objTest);

var obj1 = new Rectangle('R_1', 50, 20);
Rectangle.println(); // Static Method
console.log( obj1 );    // Rectangle {id: "R_1", width: 50, height: 20}
obj1.area;              // Area :  1000
obj1.globalValue;       // GET ID :  77777
obj1.globalValue = 88;  // SET ID :  88
obj1.globalValue;       // GET ID :  88  

var obj2 = new Rectangle('R_2', 5, 70);
console.log( obj2 );    // Rectangle {id: "R_2", width: 5, height: 70}
obj2.area;              // Area :  350    
obj2.globalValue;       // GET ID :  88
obj2.globalValue = 999; // SET ID :  999
obj2.globalValue;       // GET ID :  999

console.log('Static Variable Actions.');
obj1.globalValue;        // GET ID :  999

console.log('Parent Class Static variables');
obj1.getStaticVar();    // GET Instance Method Parent Class Static Value :  777
obj1.setStaticVar(7);   // SET Instance Method Parent Class Static Value :  7
obj1.getStaticVar();    // GET Instance Method Parent Class Static Value :  7

स्थैतिक विधि कॉल सीधे क्लास पर किए जाते हैं और क्लास के इंस्टेंस पर कॉल करने योग्य नहीं होते हैं। लेकिन आप एक उदाहरण के अंदर से स्थैतिक सदस्यों के लिए कॉल प्राप्त कर सकते हैं।

वाक्य रचना का उपयोग करना:

   this.constructor.staticfunctionName();
class MyClass {
    constructor() {}
    static staticMethod() {
        console.log('Static Method');
    }
}
MyClass.staticVar = 777;

var myInstance = new MyClass();
// calling from instance
myInstance.constructor.staticMethod();
console.log('From Inside Class : ',myInstance.constructor.staticVar);

// calling from class
MyClass.staticMethod();
console.log('Class : ', MyClass.staticVar);

ES6 क्लासेस: ES2015 कक्षाएं प्रोटोटाइप-आधारित OO पैटर्न पर एक साधारण चीनी हैं। एकल सुविधाजनक डिक्लेक्टिव फॉर्म होने से क्लास पैटर्न का उपयोग करना आसान हो जाता है, और इंटरऑपरेबिलिटी को बढ़ावा मिलता है। कक्षाएं प्रोटोटाइप-आधारित विरासत, सुपर कॉल, उदाहरण और स्थिर तरीकों और निर्माणकर्ताओं का समर्थन करती हैं।

उदाहरण : मेरी पिछली पोस्ट देखें।


2

जावास्क्रिप्ट में फ़ंक्शन-स्थानीय स्थिर चर का अनुकरण करने के 4 तरीके हैं।

विधि 1: फ़ंक्शन ऑब्जेक्ट गुण (पुराने ब्राउज़र में समर्थित) का उपयोग करना

function someFunc1(){
    if( !('staticVar' in someFunc1) )
        someFunc1.staticVar = 0 ;
    alert(++someFunc1.staticVar) ;
}

someFunc1() ; //prints 1
someFunc1() ; //prints 2
someFunc1() ; //prints 3

विधि 2: एक क्लोजर का उपयोग कर, संस्करण 1 (पुराने ब्राउज़रों में समर्थित)

var someFunc2 = (function(){
    var staticVar = 0 ;
    return function(){
        alert(++staticVar) ;
    }
})()

someFunc2() ; //prints 1
someFunc2() ; //prints 2
someFunc2() ; //prints 3

विधि 3: एक क्लोजर का उपयोग कर, संस्करण 2 (पुराने ब्राउज़रों में भी समर्थित)

var someFunc3 ;
with({staticVar:0})
    var someFunc3 = function(){
        alert(++staticVar) ;
    }

someFunc3() ; //prints 1
someFunc3() ; //prints 2
someFunc3() ; //prints 3

विधि 4: क्लोजर का उपयोग करते हुए, वेरिएंट 3 (EcmaScript 2015 के लिए समर्थन की आवश्यकता है)

{
    let staticVar = 0 ;
    function someFunc4(){
        alert(++staticVar) ;
    }
}

someFunc4() ; //prints 1
someFunc4() ; //prints 2
someFunc4() ; //prints 3

2

आप कीवर्ड का उपयोग करके जावास्क्रिप्ट में स्थिर कार्यों को परिभाषित कर सकते हैं static:

class MyClass {
  static myStaticFunction() {
    return 42;
  }
}

MyClass.myStaticFunction(); // 42

इस लेखन के रूप में, आप अभी भी वर्ग के भीतर स्थिर गुणों (कार्यों के अलावा) को परिभाषित नहीं कर सकते हैं। स्थिर गुण अभी भी एक स्टेज 3 प्रस्ताव हैं , जिसका अर्थ है कि वे अभी तक जावास्क्रिप्ट का हिस्सा नहीं हैं। हालाँकि, आपको कुछ भी करने के लिए केवल एक वर्ग को असाइन करने से रोक नहीं रहा है, जैसे कि आप किसी अन्य वस्तु पर:

class MyClass {}

MyClass.myStaticProperty = 42;

MyClass.myStaticProperty; // 42

अंतिम नोट: वंशानुक्रम के साथ स्थिर वस्तुओं का उपयोग करने के बारे में सावधान रहें - सभी विरासत वाले वर्ग वस्तु की एक ही प्रतिलिपि साझा करते हैं


1

जावास्क्रिप्ट में, कोई शब्द या कीवर्ड स्थिर नहीं है, लेकिन हम ऐसे डेटा को सीधे फ़ंक्शन ऑब्जेक्ट (किसी अन्य ऑब्जेक्ट की तरह) में डाल सकते हैं।

function f() {
    f.count = ++f.count || 1 // f.count is undefined at first
    alert("Call No " + f.count)
}

f(); // Call No 1

f(); // Call No 2

1

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

मैं निम्नलिखित विधि के साथ आया:

if (typeof Function.prototype.statics === 'undefined') {
  Function.prototype.statics = function(init) {
    if (!this._statics) this._statics = init ? init() : {};
    return this._statics;
  }
}

यह सभी कार्यों के लिए एक 'स्टेटिक्स' विधि जोड़ता है (हां, बस इसके बारे में आराम करें), जब यह कहा जाता है तो फ़ंक्शन ऑब्जेक्ट में एक खाली ऑब्जेक्ट (_statics) जोड़ देगा और इसे वापस कर देगा। यदि एक init फ़ंक्शन की आपूर्ति की जाती है तो _statics को init () परिणाम पर सेट किया जाएगा।

आप तब कर सकते हैं:

function f() {
  const _s = f.statics(() => ({ v1=3, v2=somefunc() });

  if (_s.v1==3) { ++_s.v1; _s.v2(_s.v1); }
} 

इसकी तुलना एक IIFE से करें जो अन्य सही उत्तर है, इसमें एक असाइनमेंट को जोड़ने और प्रत्येक फ़ंक्शन पर कॉल करने और फ़ंक्शन में '_statics' सदस्य को जोड़ने पर नुकसान होता है, हालांकि कुछ फायदे हैं: तर्क हैं आंतरिक फ़ंक्शन में शीर्ष नहीं, आंतरिक फ़ंक्शन कोड में 'स्टेटिक' का उपयोग करना '_s' के साथ स्पष्ट है। उपसर्ग, और यह देखने और समझने के लिए समग्र रूप से सरल है।


1

सारांश:

में ES6/ ES 2015 classकीवर्ड को एक साथ के साथ पेश किया गया था staticकीवर्ड। ध्यान रखें कि यह प्रोटोटाइप इनहेरिटेंस मॉडल के ऊपर सिंटैक्टिक शुगर है जो जावास्क्रिप्ट का प्रतीक है। staticकीवर्ड तरीकों के लिए निम्नलिखित तरीके से काम करता है:

class Dog {

  static bark () {console.log('woof');}
  // classes are function objects under the hood
  // bark method is located on the Dog function object
  
  makeSound () { console.log('bark'); }
  // makeSound is located on the Dog.prototype object

}

// to create static variables just create a property on the prototype of the class
Dog.prototype.breed = 'Pitbull';
// So to define a static property we don't need the `static` keyword.

const fluffy = new Dog();
const vicky = new Dog();
console.log(fluffy.breed, vicky.breed);

// changing the static variable changes it on all the objects
Dog.prototype.breed = 'Terrier';
console.log(fluffy.breed, vicky.breed);


2
वह स्थैतिक चर माँग रहा था, न कि स्थैतिक क्रिया।
कोनराड होफनर

1

मैंने प्रोटोटाइप का उपयोग किया और इस तरह से यह काम किया:

class Cat extends Anima {
  constructor() {
    super(Cat.COLLECTION_NAME);
  }
}

Cat.COLLECTION_NAME = "cats";

या स्टैटिक गेट्टर का उपयोग करना:

class Cat extends Anima {
  constructor() {
    super(Cat.COLLECTION_NAME);
  }

  static get COLLECTION_NAME() {
    return "cats"
  }
}

0

विंडो लेवल वर्जन को स्टैटिक्स की तरह सॉर्ट किया जाता है, जिसमें आप डायरेक्ट रेफरेंस का इस्तेमाल कर सकते हैं और ये आपके ऐप के सभी हिस्सों में उपलब्ध हैं


3
ऐसे वैरिएशन का बहुत बेहतर वर्णन 'ग्लोबल' है, न कि स्टैटिक।
पैट्रिक एम

0

जावास्क्रिप्ट में एक स्थिर चर जैसी कोई चीज नहीं है। यह भाषा प्रोटोटाइप आधारित वस्तु है, इसलिए इसमें कोई वर्ग नहीं हैं, लेकिन प्रोटोटाइप हैं जहां से वस्तुओं को "कॉपी" किया जाता है।

आप उन्हें वैश्विक चर के साथ या प्रोटोटाइप के साथ अनुकरण कर सकते हैं (एक संपत्ति को प्रोटोटाइप में जोड़कर):

function circle(){
}
circle.prototype.pi=3.14159

यह विधि काम करती है, लेकिन आप Function.prototype
Dan

@ दान: यह मेरी समझ है कि यह केवल सर्कल के लिए होगा और फ़ंक्शन नहीं होगा। कम से कम क्रोम मुझे बताने की कोशिश करता है: function circle() {}| circle.prototype| circle.prototype.pi = 3.14| circle.prototype| Function.prototype| Function.__proto__(यदि आप का यही मतलब है)
अक्तौ

0

MVC वेबसाइटों के साथ काम करना जो jQuery का उपयोग करते हैं, मुझे यह सुनिश्चित करना पसंद है कि कुछ घटना संचालकों के भीतर AJAX की कार्रवाइयों को केवल तभी निष्पादित किया जा सकता है जब पिछले अनुरोध पूरा हो गया हो। मैं इसे प्राप्त करने के लिए "स्थिर" jqXHR ऑब्जेक्ट चर का उपयोग करता हूं।

निम्नलिखित बटन दिया:

<button type="button" onclick="ajaxAction(this, { url: '/SomeController/SomeAction' })">Action!</button>

मैं अपने क्लिक हैंडलर के लिए आम तौर पर IIFE का उपयोग करता हूं:

var ajaxAction = (function (jqXHR) {
    return function (sender, args) {
        if (!jqXHR || jqXHR.readyState == 0 || jqXHR.readyState == 4) {
            jqXHR = $.ajax({
                url: args.url,
                type: 'POST',
                contentType: 'application/json',
                data: JSON.stringify($(sender).closest('form').serialize()),
                success: function (data) {
                    // Do something here with the data.
                }
            });
        }
    };
})(null);

0

यदि आप प्रोटोटाइप का उपयोग करना चाहते हैं तो एक तरीका है

var p = function Person() {
    this.x = 10;
    this.y = 20;
}
p.prototype.counter = 0;
var person1 = new p();
person1.prototype = p.prototype;
console.log(person1.counter);
person1.prototype.counter++;
var person2 = new p();
person2.prototype = p.prototype;
console.log(person2.counter);
console.log(person1.counter);

ऐसा करने से आप किसी भी उदाहरण से काउंटर चर का उपयोग करने में सक्षम होंगे और संपत्ति में कोई भी परिवर्तन तुरंत परिलक्षित होगा !!

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