टाइपस्क्रिप्ट में सिंगलटन को कैसे परिभाषित करें


128

टाइपस्क्रिप्ट में एक वर्ग के लिए सिंगलटन पैटर्न को लागू करने का सबसे अच्छा और सबसे सुविधाजनक तरीका क्या है? (आलसी प्रारंभिक के साथ और बिना दोनों)।

जवाबों:


87

टाइपस्क्रिप्ट में सिंगलटन कक्षाएं आमतौर पर एक विरोधी पैटर्न हैं। आप इसके बजाय बस नामस्थान का उपयोग कर सकते हैं ।

बेकार एकल पैटर्न

class Singleton {
    /* ... lots of singleton logic ... */
    public someMethod() { ... }
}

// Using
var x = Singleton.getInstance();
x.someMethod();

नामस्थान समतुल्य

export namespace Singleton {
    export function someMethod() { ... }
}
// Usage
import { SingletonInstance } from "path/to/Singleton";

SingletonInstance.someMethod();
var x = SingletonInstance; // If you need to alias it for some reason

55
अब यह अच्छा होगा कि सिंगलटन को एक विरोधी पैटर्न क्यों माना जाता है? इस दृष्टिकोण पर विचार करें codebelt.com/typescript/typescript-singleton-pattern
विक्टर

21
मैं जानना चाहता हूं कि टाइपस्क्रिप्ट में सिंगलेट्स को एक पैटर्न-विरोधी भी क्यों माना जाता है। और यह भी कि अगर इसके पास कोई निर्माण पैरामीटर नहीं है तो क्यों नहीं export default new Singleton()?
इमेजरो

23
नाम स्थान का समाधान एक स्थिर वर्ग की तरह दिखता है, न कि एक सिंगलटन के रूप में
Mihai Răducanu

6
यह वही व्यवहार करता है। C # में, आप एक स्थिर वर्ग को पास नहीं कर सकते हैं जैसे कि यह एक मान था (जैसे कि यह एकल वर्ग का उदाहरण था), जो इसकी उपयोगिता को सीमित करता है। टाइपस्क्रिप्ट में, आप एक उदाहरण की तरह नामस्थान पास कर सकते हैं। इसलिए आपको एकल वर्ग की आवश्यकता नहीं है।
रयान कैवानुआग

13
सिंगल्सटन के रूप में एक नाम स्थान का उपयोग करने की एक सीमा यह है कि यह (मेरे ज्ञान के लिए) एक इंटरफ़ेस लागू नहीं कर सकता है। क्या आप इस बात से सहमत होंगे @ryan
Gabe O'Leary

182

टीएस 2.0 के बाद से, हमारे पास कंस्ट्रक्टर्स पर दृश्यता संशोधक को परिभाषित करने की क्षमता है , इसलिए अब हम टाइपस्क्रिप्ट में सिंगलेट्स कर सकते हैं जैसे हम अन्य भाषाओं से उपयोग करते हैं।

उदाहरण दिया गया:

class MyClass
{
    private static _instance: MyClass;

    private constructor()
    {
        //...
    }

    public static get Instance()
    {
        // Do you need arguments? Make it a regular static method instead.
        return this._instance || (this._instance = new this());
    }
}

const myClassInstance = MyClass.Instance;

आपको यह बताने के लिए @Drenai धन्यवाद है कि यदि आप कच्चे संकलित जावास्क्रिप्ट का उपयोग करते हुए कोड लिखते हैं, तो आपको कई तात्कालिकता से सुरक्षा नहीं मिलेगी, क्योंकि TS की बाधाएं गायब हो जाती हैं और निर्माणकर्ता छिपा नहीं होगा।


2
कंस्ट्रक्टर निजी हो सकता है?
विशेषज्ञ

2
@Expertwannabe यह अब TS 2.0 में उपलब्ध है: github.com/Microsoft/TypeScript/wiki/…
एलेक्स '

3
यह मेरा पसंदीदा उत्तर है! धन्यवाद।
मार्टिन माजूस्की

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

3
@ किमचीमैन यदि परियोजना को कभी गैर-टाइपस्क्रिप्ट वातावरण में उपयोग किया जाता है जैसे कि जेएस परियोजना में आयात किया जाता है, तो कक्षा को आगे तात्कालिकता से कोई सुरक्षा नहीं होगी। यह केवल शुद्ध टीएस वातावरण में काम करता है, लेकिन जेएस लाइब्रेरी के विकास के लिए नहीं
Drenai

39

सबसे अच्छा तरीका मैंने पाया है:

class SingletonClass {

    private static _instance:SingletonClass = new SingletonClass();

    private _score:number = 0;

    constructor() {
        if(SingletonClass._instance){
            throw new Error("Error: Instantiation failed: Use SingletonClass.getInstance() instead of new.");
        }
        SingletonClass._instance = this;
    }

    public static getInstance():SingletonClass
    {
        return SingletonClass._instance;
    }

    public setScore(value:number):void
    {
        this._score = value;
    }

    public getScore():number
    {
        return this._score;
    }

    public addPoints(value:number):void
    {
        this._score += value;
    }

    public removePoints(value:number):void
    {
        this._score -= value;
    }

}

यहाँ आप इसका उपयोग कैसे करें:

var scoreManager = SingletonClass.getInstance();
scoreManager.setScore(10);
scoreManager.addPoints(1);
scoreManager.removePoints(2);
console.log( scoreManager.getScore() );

https://codebelt.github.io/blog/typescript/typescript-singleton-pattern/


3
कंस्ट्रक्टर को निजी क्यों नहीं बनाया?
फिल मंडर

4
मुझे लगता है कि पोस्ट टीएस में निजी निर्माणकर्ताओं की क्षमता की भविष्यवाणी करता है। github.com/Microsoft/TypeScript/issues/2341
ट्रेवर

मुझे यह उत्तर पसंद है। निजी कंस्ट्रक्टर विकास के दौरान महान हैं, लेकिन अगर एक ट्रांसस्प्लेड टीएस मॉड्यूल जेएस वातावरण में आयात किया जाता है, तो कंस्ट्रक्टर अभी भी एक्सेस किया जा सकता है। इस दृष्टिकोण के साथ इसका दुरुपयोग के खिलाफ लगभग संरक्षित है .... जब तक कि सिंग्लटनक्लास ['_ उदाहरण'] शून्य / अपरिभाषित पर सेट नहीं है
Drenai

लिंक टूट गया है। मुझे लगता है कि यह वास्तविक लिंक है: codebelt.github.io/blog/typescript/typescript-singleton-pattern
El Asiduo

24

निम्नलिखित दृष्टिकोण एक सिंगलटन वर्ग बनाता है जिसे पारंपरिक कक्षा की तरह इस्तेमाल किया जा सकता है:

class Singleton {
    private static instance: Singleton;
    //Assign "new Singleton()" here to avoid lazy initialisation

    constructor() {
        if (Singleton.instance) {
            return Singleton.instance;
        }

        this. member = 0;
        Singleton.instance = this;
    }

    member: number;
}

प्रत्येक new Singleton()ऑपरेशन एक ही उदाहरण लौटाएगा। हालांकि यह उपयोगकर्ता द्वारा अप्रत्याशित हो सकता है।

निम्न उदाहरण उपयोगकर्ता के लिए अधिक पारदर्शी है लेकिन इसके लिए एक अलग उपयोग की आवश्यकता है:

class Singleton {
    private static instance: Singleton;
    //Assign "new Singleton()" here to avoid lazy initialisation

    constructor() {
        if (Singleton.instance) {
            throw new Error("Error - use Singleton.getInstance()");
        }
        this.member = 0;
    }

    static getInstance(): Singleton {
        Singleton.instance = Singleton.instance || new Singleton();
        return Singleton.instance;
    }

    member: number;
}

उपयोग: var obj = Singleton.getInstance();


1
यह वह तरीका है, जिसे लागू किया जाना चाहिए। अगर वहाँ 1 बात मैं चार के गैंग से असहमत हूँ - और यह शायद केवल 1 है - इसका सिंगलटन पैटर्न। शायद, C / ++ एक को इस तरह से डिजाइन करने से रोकता है। लेकिन अगर आप मुझसे पूछते हैं, तो क्लाइंट कोड को पता नहीं होना चाहिए कि क्या इसकी देखभाल है या नहीं। ग्राहकों को अभी भी new Class(...)वाक्यविन्यास लागू करना चाहिए ।
कोड़ी

16

मैं निम्नलिखित पैटर्न को यहां नहीं देखकर आश्चर्यचकित हूं, जो वास्तव में बहुत सरल दिखता है।

// shout.ts
class ShoutSingleton {
  helloWorld() { return 'hi'; }
}

export let Shout = new ShoutSingleton();

प्रयोग

import { Shout } from './shout';
Shout.helloWorld();

मुझे निम्न त्रुटि संदेश मिला: निर्यातित चर 'Shout' में निजी नाम 'ShoutSingleton' का उपयोग किया गया है।
दो

3
आपको वर्ग 'ShoutSingleton' को भी निर्यात करना होगा, और त्रुटि गायब हो जाएगी।
दो

वहीं, मैं भी हैरान हूं। हालांकि कक्षा के साथ भी क्यों परेशान? सिंगलटन को अपने आंतरिक कामकाज को छिपाना चाहिए। क्यों न सिर्फ फंक्शन हेलोवर्ल्ड निर्यात करें?
ओलेग डुलिन

अधिक जानकारी के लिए इस github मुद्दे को देखें: github.com/Microsoft/TypeScript/issues/6307
Ore4444

5
लगता है कि कुछ भी नहीं उपयोगकर्ताओं को सिर्फ एक नई Shoutकक्षा बनाने से रोक रहा है
d

7

आप इसके लिए कक्षा के भावों का उपयोग कर सकते हैं (जैसा कि मैं मानता हूं 1.6)।

var x = new (class {
    /* ... lots of singleton logic ... */
    public someMethod() { ... }
})();

या नाम के साथ अगर आपकी कक्षा को आंतरिक रूप से अपने प्रकार तक पहुंचने की आवश्यकता है

var x = new (class Singleton {
    /* ... lots of singleton logic ... */
    public someMethod(): Singleton { ... }
})();

एक अन्य विकल्प कुछ स्थिर सदस्यों का उपयोग करके अपने सिंगलटन के अंदर एक स्थानीय वर्ग का उपयोग करना है

class Singleton {

    private static _instance;
    public static get instance() {

        class InternalSingleton {
            someMethod() { }

            //more singleton logic
        }

        if(!Singleton._instance) {
            Singleton._instance = new InternalSingleton();
        }

        return <InternalSingleton>Singleton._instance;
    }
}

var x = Singleton.instance;
x.someMethod();

7

इसे "सिंगलटन" बनाने के लिए किसी भी वर्ग के लिए निम्नलिखित 6 पंक्तियों को जोड़ें।

class MySingleton
{
    private constructor(){ /* ... */}
    private static _instance: MySingleton;
    public static getInstance(): MySingleton
    {
        return this._instance || (this._instance = new this());
    };
}

परीक्षण उदाहरण:

var test = MySingleton.getInstance(); // will create the first instance
var test2 = MySingleton.getInstance(); // will return the first instance
alert(test === test2); // true

[संपादित करें] यदि आप किसी संपत्ति के बजाय एक विधि के माध्यम से उदाहरण प्राप्त करना पसंद करते हैं तो एलेक्स उत्तर का उपयोग करें।


जब मैं new MySingleton()5 बार बोलूं तो क्या होगा ? क्या आपका कोड एकल उदाहरण आरक्षित करता है?
हलवुलेका मास्क

आपको कभी भी "नया" का उपयोग नहीं करना चाहिए: जैसा कि एलेक्स ने लिखा है, निर्माणकर्ता को "निजी" होना चाहिए, जिससे "नए मायसिंगटन ()" को रोका जा सके। सही उपयोग MySingleton.getInstance () का उपयोग करके एक उदाहरण प्राप्त करना है। AKAIK नो कंस्ट्रक्टर (जैसे मेरे उदाहरण में) = एक सार्वजनिक खाली कंस्ट्रक्टर
फ्लाविएन वोल्केन

"आपको कभी भी नए" का उपयोग नहीं करना चाहिए - बिल्कुल मेरी बात: "। लेकिन आपका कार्यान्वयन मुझे ऐसा करने से कैसे रोकता है? मैं कहीं नहीं देखता कि आपकी कक्षा में आपके पास निजी कंस्ट्रक्टर कहां है?
हलवुलेका मास

@ हलावुल्कामास मैं नहीं था ... इसलिए मैंने उत्तर को संपादित किया, ध्यान दें कि टीएस 2.0 से पहले एक निजी निर्माण संभव नहीं था (यानी उस समय मैंने पहले उत्तर लिखा था)
फ्लाविएन वोल्केन

"अर्थात उस समय मैंने पहले उत्तर लिखा था" - समझ में आता है। ठंडा।
हेलावुल्का एमएएस

3

मुझे लगता है कि शायद जेनरिक बल्लेबाज का उपयोग करें

class Singleton<T>{
    public static Instance<T>(c: {new(): T; }) : T{
        if (this._instance == null){
            this._instance = new c();
        }
        return this._instance;
    }

    private static _instance = null;
}

कैसे इस्तेमाल करे

चरण 1

class MapManager extends Singleton<MapManager>{
     //do something
     public init():void{ //do }
}

चरण 2

    MapManager.Instance(MapManager).init();

3

आप फ़ंक्शन ऑब्जेक्ट का उपयोग भी कर सकते हैं । फ़्रीज़ () । इसका सरल और आसान:

class Singleton {

  instance: any = null;
  data: any = {} // store data in here

  constructor() {
    if (!this.instance) {
      this.instance = this;
    }
    return this.instance
  }
}

const singleton: Singleton = new Singleton();
Object.freeze(singleton);

export default singleton;

केनी, फ्रीज पर अच्छी बात (), लेकिन दो नोट: (1) आपके द्वारा फ्रीज करने के बाद (सिंगलटन), आप अभी भी सिंगलटन.डेटा को संशोधित कर सकते हैं .. आप अन्य विशेषता (जैसे डेटा 2) नहीं जोड़ सकते, लेकिन बिंदु यह है कि फ्रीज ( ) डीप फ्रीज नहीं है :) और (2) आपकी क्लास सिंगलटन एक से अधिक उदाहरण बनाने की अनुमति देती है (उदाहरण obj1 = new Singleton (); obj2 = new सिंगलटन);), इसलिए आपका सिंगलटन सिंगलटन नहीं है
:)

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

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

सच है, लेकिन इस मामले में यह होगा, क्योंकि निर्यात किया गया सदस्य पहले से ही एक उदाहरण है। और उदाहरण डेटा रखता है। यदि आप कक्षा में भी निर्यात करते हैं, तो आप सही हैं और आप कई उदाहरण बना सकते हैं।
केनी

@ पता है कि अगर आप जानते हैं कि आप एक उदाहरण का निर्यात करने जा रहे हैं, if (!this.instance)तो कंस्ट्रक्टर में परेशान क्यों हों ? क्या आपने निर्यात से पहले कई उदाहरण बनाए हैं, तो यह सिर्फ एक अतिरिक्त सावधानी है?
एलेक्स

2

मुझे इसका एक नया संस्करण मिला है कि टाइपस्क्रिप्ट कंपाइलर के साथ पूरी तरह से ठीक है, और मुझे लगता है कि यह बेहतर है क्योंकि इसे getInstance()लगातार एक विधि को कॉल करने की आवश्यकता नहीं है ।

import express, { Application } from 'express';

export class Singleton {
  // Define your props here
  private _express: Application = express();
  private static _instance: Singleton;

  constructor() {
    if (Singleton._instance) {
      return Singleton._instance;
    }

    // You don't have an instance, so continue

    // Remember, to set the _instance property
    Singleton._instance = this;
  }
}

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


1

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

सबसे पहले आप में एक सिंगलटन वर्ग की जरूरत है, के, मान लीजिए "./utils/Singleton.ts" :

module utils {
    export class Singleton {
        private _initialized: boolean;

        private _setSingleton(): void {
            if (this._initialized) throw Error('Singleton is already initialized.');
            this._initialized = true;
        }

        get setSingleton() { return this._setSingleton; }
    }
}

अब कल्पना करें कि आपको एक राउटर सिंगलटन की आवश्यकता है "./navigation/Router.ts" :

/// <reference path="../utils/Singleton.ts" />

module navigation {
    class RouterClass extends utils.Singleton {
        // NOTICE RouterClass extends from utils.Singleton
        // and that it isn't exportable.

        private _init(): void {
            // This method will be your "construtor" now,
            // to avoid double initialization, don't forget
            // the parent class setSingleton method!.
            this.setSingleton();

            // Initialization stuff.
        }

        // Expose _init method.
        get init { return this.init; }
    }

    // THIS IS IT!! Export a new RouterClass, that no
    // one can instantiate ever again!.
    export var Router: RouterClass = new RouterClass();
}

अच्छा !, अब जहाँ भी आपको आवश्यकता हो, आरंभ या आयात करें:

/// <reference path="./navigation/Router.ts" />

import router = navigation.Router;

router.init();
router.init(); // Throws error!.

इस तरह से एकल करने के बारे में अच्छी बात यह है कि आप अभी भी टाइपस्क्रिप्ट कक्षाओं की सभी सुंदरता का उपयोग करते हैं, यह आपको अच्छा परिचय देता है, सिंगलटन तर्क किसी को अलग रखता है और यदि आवश्यक हो तो निकालना आसान है।


1

इसके लिए मेरा समाधान:

export default class Modal {
    private static _instance : Modal = new Modal();

    constructor () {
        if (Modal._instance) 
            throw new Error("Use Modal.instance");
        Modal._instance = this;
    }

    static get instance () {
        return Modal._instance;
    }
}

1
कंस्ट्रक्टर में, अपवाद के बजाय आप कर सकते हैं return Modal._instance। इस तरह, यदि आप newउस वर्ग को, आप मौजूदा वस्तु प्राप्त करते हैं, तो नया नहीं।
मिहाई राउडुकेनू

1

टाइपस्क्रिप्ट में, किसी को आवश्यक रूप से new instance()सिंगलटन पद्धति का पालन नहीं करना पड़ता है । एक आयातित, कंस्ट्रक्टर-कम स्थिर वर्ग समान रूप से भी काम कर सकता है।

विचार करें:

export class YourSingleton {

   public static foo:bar;

   public static initialise(_initVars:any):void {
     YourSingleton.foo = _initvars.foo;
   }

   public static doThing():bar {
     return YourSingleton.foo
   }
}

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

import {YourSingleton} from 'singleton.ts';

YourSingleton.initialise(params);
let _result:bar = YourSingleton.doThing();

यह मत भूलो कि एक स्थिर वर्ग में, प्रत्येक विधि और चर को भी स्थिर होने की आवश्यकता होती है, इसलिए इसके बजाय thisआप पूर्ण वर्ग नाम का उपयोग करेंगे YourSingleton


0

यहाँ IFFE का उपयोग करके अधिक पारंपरिक जावास्क्रिप्ट दृष्टिकोण के साथ करने का एक और तरीका है :

module App.Counter {
    export var Instance = (() => {
        var i = 0;
        return {
            increment: (): void => {
                i++;
            },
            getCount: (): number => {
                return i;
            }
        }
    })();
}

module App {
    export function countStuff() {
        App.Counter.Instance.increment();
        App.Counter.Instance.increment();
        alert(App.Counter.Instance.getCount());
    }
}

App.countStuff();

एक डेमो देखें


Instanceचर जोड़ने का क्या कारण है ? आप बस सीधे चर और कार्यों को सीधे नीचे रखते हैं App.Counter
फिया

@fyaa हाँ, आप कर सकते हैं लेकिन चर और फ़ंक्शन सीधे App.Counter के तहत लेकिन मुझे लगता है कि यह दृष्टिकोण सिंगलटन पैटर्न en.wikipedia.org/wiki/Singleton_pattern के लिए बेहतर अनुरूप है ।
जेसपारा

0

एक अन्य विकल्प अपने मॉड्यूल में प्रतीकों का उपयोग करना है। इस तरह आप अपनी कक्षा की सुरक्षा कर सकते हैं, भले ही आपके एपीआई का अंतिम उपयोगकर्ता सामान्य जावास्क्रिप्ट का उपयोग कर रहा हो:

let _instance = Symbol();
export default class Singleton {

    constructor(singletonToken) {
        if (singletonToken !== _instance) {
            throw new Error("Cannot instantiate directly.");
        }
        //Init your class
    }

    static get instance() {
        return this[_instance] || (this[_instance] = new Singleton(_singleton))
    }

    public myMethod():string {
        return "foo";
    }
}

उपयोग:

var str:string = Singleton.instance.myFoo();

यदि उपयोगकर्ता आपकी संकलित एपीआई जेएस फ़ाइल का उपयोग कर रहा है, तो भी एक त्रुटि मिलेगी यदि वह मैन्युअल रूप से आपकी कक्षा को तुरंत करने की कोशिश करता है:

// PLAIN JAVASCRIPT: 
var instance = new Singleton(); //Error the argument singletonToken !== _instance symbol

0

एक शुद्ध सिंगलटन नहीं (आरंभीकरण आलसी नहीं हो सकता), लेकिन namespaceएस की मदद से समान पैटर्न ।

namespace MyClass
{
    class _MyClass
    {
    ...
    }
    export const instance: _MyClass = new _MyClass();
}

सिंगलटन की वस्तु तक पहुंच:

MyClass.instance

0

यह सबसे सरल तरीका है

class YourSingletoneClass {
  private static instance: YourSingletoneClass;

  private constructor(public ifYouHaveAnyParams: string) {

  }
  static getInstance() {
    if(!YourSingletoneClass.instance) {
      YourSingletoneClass.instance = new YourSingletoneClass('If you have any params');
    }
    return YourSingletoneClass.instance;
  }
}

-1
namespace MySingleton {
  interface IMySingleton {
      doSomething(): void;
  }
  class MySingleton implements IMySingleton {
      private usePrivate() { }
      doSomething() {
          this.usePrivate();
      }
  }
  export var Instance: IMySingleton = new MySingleton();
}

इस तरह हम एक इंटरफ़ेस लागू कर सकते हैं, रेयान कैवानुग के स्वीकृत उत्तर के विपरीत।


-1

इस धागे को खंगालने और उपरोक्त सभी विकल्पों के साथ खेलने के बाद - मैंने एक सिंगलटन के साथ समझौता किया जिसे उचित निर्माणकर्ताओं के साथ बनाया जा सकता है:

export default class Singleton {
  private static _instance: Singleton

  public static get instance(): Singleton {
    return Singleton._instance
  }

  constructor(...args: string[]) {
    // Initial setup

    Singleton._instance = this
  }

  work() { /* example */ }

}

इसके लिए प्रारंभिक सेटअप ( main.ts, या index.ts,) की आवश्यकता होती है , जिसे आसानी से लागू किया जा सकता है
new Singleton(/* PARAMS */)

फिर, आपके कोड में कहीं भी, बस कॉल करें Singleton.instnace; इस मामले में, करने के लिए work, मैं फोन करूंगाSingleton.instance.work()


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