क्या जावास्क्रिप्ट में इंटरफ़ेस प्रकार (जैसे जावा का 'इंटरफ़ेस') है?


324

मैं जावास्क्रिप्ट के साथ OOP बनाना सीख रहा हूँ । क्या इसकी इंटरफ़ेस अवधारणा (जैसे जावा की interface) है?

तो मैं एक श्रोता बनाने में सक्षम हो जाएगा ...


18
अधिक विकल्पों की तलाश करने वालों के लिए टाइपस्क्रिप्ट में इंटरफेस होते हैं
एसडी

2
एक अन्य विकल्प यदि आप वैनिला जेएस का उपयोग करना चाहते हैं , तो इसे लागू किया गया है
रिचर्ड लोवेल

जवाबों:


648

"इस वर्ग के पास ये कार्य होने चाहिए" की कोई धारणा नहीं है (अर्थात, प्रति क्रमांक नहीं), क्योंकि:

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

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

अब, यदि आपका फोन कॉल करने की कोशिश नहीं करता है, तो आपका कोड आधे से भी कम नहीं होगा some_dog.quack(); आपको एक टाइपर्रर मिलेगा। सच कहूं, अगर आप कुत्तों को शांत करने के लिए कह रहे हैं, तो आपको थोड़ी बड़ी समस्याएं हैं; जब आप अपने सभी बत्तख को एक पंक्ति में रखते हैं, तो बोलने के लिए बतख टाइपिंग सबसे अच्छा काम करती है, और जब तक आप उन्हें सामान्य जानवरों के रूप में नहीं मान रहे हैं, तब तक कुत्तों और बत्तखों को एक साथ नहीं होने दें। दूसरे शब्दों में, भले ही इंटरफ़ेस तरल है, यह अभी भी है; यह अक्सर एक कुत्ते को पास करने के लिए एक त्रुटि है जो इसे पहले स्थान पर छोड़ने और उड़ने की उम्मीद करता है।

लेकिन अगर आपको यकीन है कि आप सही काम कर रहे हैं, तो आप इसे इस्तेमाल करने की कोशिश करने से पहले किसी विशेष विधि के अस्तित्व के लिए परीक्षण करके क्वैकिंग-डॉग समस्या के आसपास काम कर सकते हैं। कुछ इस तरह

if (typeof(someObject.quack) == "function")
{
    // This thing can quack
}

इसलिए आप उन सभी तरीकों की जांच कर सकते हैं जिनका उपयोग करने से पहले आप उनका उपयोग कर सकते हैं। सिंटैक्स एक प्रकार का बदसूरत है, हालांकि। थोड़ा प्रीतिकर तरीका है:

Object.prototype.can = function(methodName)
{
     return ((typeof this[methodName]) == "function");
};

if (someObject.can("quack"))
{
    someObject.quack();
}

यह मानक जावास्क्रिप्ट है, इसलिए इसका उपयोग करने लायक किसी भी जेएस दुभाषिया में काम करना चाहिए। इसमें अंग्रेजी की तरह पढ़ने का अतिरिक्त लाभ है।

आधुनिक ब्राउज़रों के लिए (अर्थात, IE 6-8 के अलावा कोई भी ब्राउज़र), संपत्ति को दिखाने से रखने का एक तरीका भी है for...in:

Object.defineProperty(Object.prototype, 'can', {
    enumerable: false,
    value: function(method) {
        return (typeof this[method] === 'function');
    }
}

समस्या यह है कि IE7 ऑब्जेक्ट्स के पास बिल्कुल नहीं है .defineProperty, और IE8 में, यह कथित तौर पर केवल होस्ट ऑब्जेक्ट्स (यानी, DOM एलिमेंट्स और ऐसे) पर काम करता है। यदि संगतता एक समस्या है, तो आप उपयोग नहीं कर सकते .defineProperty। (मैं IE6 का उल्लेख भी नहीं करूंगा, क्योंकि यह चीन के बाहर अब अप्रासंगिक है।)

एक और मुद्दा यह है कि कुछ कोडिंग शैली यह मान लेना पसंद करती हैं कि हर कोई खराब कोड लिखता है, और Object.prototypeयदि कोई आँख बंद करके उपयोग करना चाहता है तो उसे संशोधित करना प्रतिबंधित है for...in। यदि आप इस बारे में परवाह करते हैं, या (IMO टूटा हुआ ) कोड का उपयोग कर रहे हैं , तो थोड़ा अलग संस्करण आज़माएँ:

function can(obj, methodName)
{
     return ((typeof obj[methodName]) == "function");
}

if (can(someObject, "quack"))
{
    someObject.quack();
}

7
यह उतना भयानक नहीं है जितना कि यह बनाया गया है। for...inहै - और हमेशा ऐसे खतरों से भरा हुआ है, और जो कोई भी ऐसा करता है, वह कम से कम यह विचार किए बिना करता है कि किसी ने जोड़ा Object.prototype(एक असामान्य तकनीक नहीं है, उस लेख के स्वयं के प्रवेश द्वारा) किसी और के हाथों में अपने कोड को तोड़ देगा।
cHao

1
@entonio: मैं एक समस्या के बजाय एक सुविधा के रूप में अंतर्निहित प्रकार की मॉलबिलिटी पर विचार करूंगा । यह क्या shims / polyfills संभव बनाता है का एक बड़ा हिस्सा है। इसके बिना, हम या तो सभी अंतर्निहित प्रकारों को संभवतः-असंगत उप-प्रकारों के साथ लपेट सकते हैं या सार्वभौमिक ब्राउज़र समर्थन की प्रतीक्षा कर रहे हैं (जो कि कभी नहीं आ सकता है, जब ब्राउज़र सामान का समर्थन नहीं करते हैं लोग इसका उपयोग नहीं करते हैं क्योंकि यह ब्राउज़र डॉन का कारण नहीं बनता है ' टी इसे समर्थन)। क्योंकि अंतर्निहित प्रकारों को संशोधित किया जा सकता है, हम इसके बजाय कई कार्यों को जोड़ सकते हैं जो अभी तक मौजूद नहीं हैं।
cHao

1
जावास्क्रिप्ट (1.8.5) के पिछले संस्करण में आप एक वस्तु की संपत्ति होने के लिए परिभाषित कर सकते हैं नहीं गणनीय। इस तरह आप for...inसमस्या से बच सकते हैं । developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
टॉमस प्राडो

1
@ Tomás: अफसोस की बात है, हर ब्राउज़र में ts ES5 के साथ संगत चल रहा है, हमें अभी भी इस तरह से सामान के बारे में चिंता करना होगा। और फिर भी, " for...inसमस्या" अभी भी कुछ हद तक मौजूद होगी, क्योंकि वहाँ हमेशा मैला कोड होगा ... ठीक है, वह, और Object.defineProperty(obj, 'a', {writable: true, enumerable: false, value: 3});बस की तुलना में थोड़ा अधिक काम है obj.a = 3;। मैं पूरी तरह से समझ सकता हूं कि लोग इसे अधिक बार करने की कोशिश नहीं कर रहे हैं। : P
cHao

1
हेहे ... प्यार से "सच कहूँ, अगर आप कुत्तों को शांत करने के लिए कह रहे हैं, तो आपके पास थोड़ी बड़ी समस्याएं हैं। यह दिखाने के लिए महान सादृश्य है कि भाषाओं को मूर्खता से बचने की कोशिश नहीं करनी चाहिए। यह हमेशा एक हारी हुई लड़ाई है। -स्कॉट
स्कूपा। कॉम

72

डस्टिन डियाज़ द्वारा ' जावास्क्रिप्ट डिज़ाइन पैटर्न ' की एक प्रति उठाओ । डक टाइपिंग के माध्यम से जावास्क्रिप्ट इंटरफेस को लागू करने के लिए समर्पित कुछ अध्याय हैं। यह एक अच्छा पढ़ने के रूप में अच्छी तरह से है। लेकिन नहीं, इंटरफ़ेस का कोई भाषा मूल कार्यान्वयन नहीं है, आपको डक टाइप करना होगा

// example duck typing method
var hasMethods = function(obj /*, method list as strings */){
    var i = 1, methodName;
    while((methodName = arguments[i++])){
        if(typeof obj[methodName] != 'function') {
            return false;
        }
    }
    return true;
}

// in your code
if(hasMethods(obj, 'quak', 'flapWings','waggle')) {
    //  IT'S A DUCK, do your duck thang
}

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

21

जावास्क्रिप्ट (ECMAScript संस्करण 3) में भविष्य के उपयोग के लिएimplements आरक्षित शब्द है । मुझे लगता है कि यह वास्तव में इस उद्देश्य के लिए है, हालांकि, विनिर्देश को प्राप्त करने के लिए एक भीड़ में, उनके पास यह निर्धारित करने के लिए समय नहीं था कि इसके साथ क्या करना है, इसलिए, वर्तमान समय में, ब्राउज़र इसके अलावा कुछ भी नहीं करते हैं यदि आप इसे किसी चीज़ के लिए उपयोग करने का प्रयास करते हैं, तो इसे वहां बैठें और कभी-कभी शिकायत करें।

यह संभव है और Object.implement(Interface)तर्क के साथ अपनी खुद की विधि बनाने के लिए वास्तव में काफी आसान है, जब भी किसी विशेष वस्तु में गुणों / कार्यों का एक विशेष सेट लागू नहीं होता है।

मैंने ऑब्जेक्ट-ओरिएंटेशन पर एक लेख लिखा है, जहां निम्नानुसार मेरे अपने अंकन का उपयोग करें :

// Create a 'Dog' class that inherits from 'Animal'
// and implements the 'Mammal' interface
var Dog = Object.extend(Animal, {
    constructor: function(name) {
        Dog.superClass.call(this, name);
    },
    bark: function() {
        alert('woof');
    }
}).implement(Mammal);

इस विशेष बिल्ली को त्वचा करने के कई तरीके हैं, लेकिन यह वह तर्क है जिसका उपयोग मैंने अपने स्वयं के इंटरफ़ेस कार्यान्वयन के लिए किया था। मुझे लगता है कि मैं इस दृष्टिकोण को पसंद करता हूं, और इसे पढ़ना और उपयोग करना आसान है (जैसा कि आप ऊपर देख सकते हैं)। इसका मतलब है एक 'लागू' पद्धति को जोड़ना Function.prototypeजिससे कुछ लोगों को समस्या हो सकती है, लेकिन मुझे लगता है कि यह खूबसूरती से काम करता है।

Function.prototype.implement = function() {
    // Loop through each interface passed in and then check 
    // that its members are implemented in the context object (this).
    for(var i = 0; i < arguments.length; i++) {
       // .. Check member's logic ..
    }
    // Remember to return the class being tested
    return this;
}

4
यह वाक्यविन्यास वास्तव में मेरे मस्तिष्क को चोट पहुंचाता है, लेकिन यहां कार्यान्वयन काफी दिलचस्प है।
साइफर

2
जावास्क्रिप्ट OO भाषा कार्यान्वयन से आने वाले विशेष रूप से (मस्तिष्क को चोट पहुँचाने) करने के लिए बाध्य है।
स्टीवन डी सलास

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

"// .. सदस्य के तर्क की जाँच करें।" ? वह किस तरह का दिखता है?
पॉजिटिव

हाय @ हम, सदस्यों के तर्क की जाँच करने का अर्थ है वांछित गुणों के माध्यम से लूप करना और एक त्रुटि को फेंकना यदि कोई गायब है .. की तर्ज पर कुछ var interf = arguments[i]; for (prop in interf) { if (this.prototype[prop] === undefined) { throw 'Member [' + prop + '] missing from class definition.'; }}। अधिक विस्तृत उदाहरण के लिए लेख लिंक के नीचे देखें ।
स्टीवन डी सलास

12

जावास्क्रिप्ट इंटरफेस:

हालाँकि जावास्क्रिप्ट का प्रकार नहीं है interface, अक्सर इसकी आवश्यकता होती है। जावास्क्रिप्ट के गतिशील प्रकृति और प्रोटोटाइप-इनहेरिटेंस के उपयोग से संबंधित कारणों के लिए, कक्षाओं में लगातार इंटरफेस सुनिश्चित करना मुश्किल है - हालांकि, ऐसा करना संभव है; और अक्सर अनुकरण किया।

इस बिंदु पर, जावास्क्रिप्ट में इंटरफेसेस का अनुकरण करने के लिए कुछ विशेष तरीके हैं; दृष्टिकोण पर भिन्नता आम तौर पर कुछ जरूरतों को संतुष्ट करती है, जबकि अन्य को अनसुना कर दिया जाता है। अक्सर बार, सबसे मजबूत दृष्टिकोण अत्यधिक बोझिल होता है और कार्यान्वयनकर्ता (डेवलपर) को स्तब्ध कर देता है।

यहाँ Interfaces / Abstract Classes के लिए एक दृष्टिकोण दिया गया है जो बहुत बोझिल नहीं है, खोजपूर्ण है, संक्षेप के अंदर कार्यान्वयन को कम से कम रखता है, और गतिशील या कस्टम कार्यप्रणाली के लिए पर्याप्त जगह छोड़ता है:

function resolvePrecept(interfaceName) {
    var interfaceName = interfaceName;
    return function curry(value) {
        /*      throw new Error(interfaceName + ' requires an implementation for ...');     */
        console.warn('%s requires an implementation for ...', interfaceName);
        return value;
    };
}

var iAbstractClass = function AbstractClass() {
    var defaultTo = resolvePrecept('iAbstractClass');

    this.datum1 = this.datum1 || defaultTo(new Number());
    this.datum2 = this.datum2 || defaultTo(new String());

    this.method1 = this.method1 || defaultTo(new Function('return new Boolean();'));
    this.method2 = this.method2 || defaultTo(new Function('return new Object();'));

};

var ConcreteImplementation = function ConcreteImplementation() {

    this.datum1 = 1;
    this.datum2 = 'str';

    this.method1 = function method1() {
        return true;
    };
    this.method2 = function method2() {
        return {};
    };

    //Applies Interface (Implement iAbstractClass Interface)
    iAbstractClass.apply(this);  // .call / .apply after precept definitions
};

प्रतिभागियों

रिसॉल्वर को प्रिसेप्ट करें

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

iAbstractClass

iAbstractClassइंटरफ़ेस प्रयोग की जाने वाली परिभाषित करता है। इसका दृष्टिकोण अपने कार्यान्वयनकर्ता वर्ग के साथ एक मौन समझौता करता है। यह इंटरफ़ेस प्रत्येक प्रीसेप्ट को एक ही सटीक प्रीसेप्ट नामस्थान - या - जो कुछ भी प्रेज़ॉल रिज़ॉल्वर फ़ंक्शन देता है, प्रदान करता है। हालांकि, टैसिट समझौता एक संदर्भ में लागू होता है - कार्यान्वयन का एक प्रावधान।

implementor

Implementor बस (एक अंतरफलक के साथ 'इस बात से सहमत' iAbstractClass इस मामले में) और के उपयोग के द्वारा यह लागू होता है निर्माता-अपहरण : iAbstractClass.apply(this)। ऊपर दिए गए डेटा और व्यवहार को परिभाषित करके, और फिर इंटरफ़ेस के निर्माता को हाईजैक करना - इंटरफ़ेस निर्माता के लिए कार्यान्वयन के संदर्भ को पारित करना - हम यह सुनिश्चित कर सकते हैं कि कार्यान्वयन का ओवरराइड जोड़ा जाएगा, और वह इंटरफ़ेस चेतावनी और डिफ़ॉल्ट मानों की खोज करेगा।

यह एक बहुत ही गैर-बोझिल दृष्टिकोण है जिसने समय और विभिन्न परियोजनाओं के लिए मेरी टीम और मैंने बहुत अच्छी तरह से सेवा की है। हालाँकि, इसमें कुछ कैविटीज़ और कमियां हैं।

कमियां

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

यह प्रतीत होता है "जावास्क्रिप्ट में इंटरफेस" के लिए सबसे अच्छा तरीका है , हालांकि, मैं निम्नलिखित हल देखना पसंद करूंगा:

  • वापसी के प्रकार के दावे
  • हस्ताक्षर के दावे
  • वस्तुओं को deleteकार्यों से मुक्त करें
  • जावास्क्रिप्ट समुदाय की विशिष्टता में कुछ और प्रचलित या आवश्यक है

उस ने कहा, मुझे आशा है कि इससे आपको उतना ही मदद मिलेगी, जितना कि मेरी टीम और मैं।


7

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


1
वास्तव में, आपको जावा में इंटरफेस की आवश्यकता नहीं है, यह सुनिश्चित करने के लिए सुरक्षित नहीं है कि वस्तुओं में एक निश्चित एपीआई है ताकि आप उन्हें अन्य कार्यान्वयन के लिए स्वैप कर सकें।
BGerrissen

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

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

2
@entonio: डिस्पैच उतना गतिशील नहीं है जितना दिखता है। वास्तविक विधि को अक्सर बहुमान्यता के लिए झुकाव रनटाइम के रूप में नहीं जाना जाता है, लेकिन बाइटकोड को "अपने एमथोड को लागू करना" नहीं कहता है; यह कहता है "Superclass.yourMethod आह्वान करें"। JVM यह जाने बिना कि किस कक्षा में देखना चाहता है, एक विधि का आह्वान नहीं कर सकता है। लिंकिंग के दौरान, यह yourMethodप्रविष्टि # 5 की Superclassव्यवहार्यता में डाल सकता है , और प्रत्येक उपवर्ग के लिए जिसका अपना है yourMethod, बस इंगित करता है कि उपवर्ग की प्रविष्टि 5 उचित कार्यान्वयन पर।
cHao

1
@entonio: इंटरफेस के लिए, नियमों करते थोड़ा बदल जाते हैं। (भाषावार नहीं, बल्कि जेनरेट किया गया बायटेकोड और JVM का लुकअप प्रोसेस अलग-अलग है।) एक वर्ग जिसका नाम इम्प्लीमेंट है, Implementationवह SomeInterfaceयह नहीं कहता है कि यह पूरे इंटरफ़ेस को लागू करता है। इसकी जानकारी है कि "मैं लागू करता हूं" कहता है SomeInterface.yourMethodऔर इसके लिए विधि परिभाषा पर अंक देता है Implementation.yourMethod। जब JVM कॉल करता है SomeInterface.yourMethod, तो यह उस इंटरफ़ेस की विधि के कार्यान्वयन के बारे में जानकारी के लिए कक्षा में दिखता है, और पाता है कि इसे कॉल करने की आवश्यकता है Implementation.yourMethod
cHao

6

आशा है, कि जो कोई भी अभी भी उत्तर की तलाश में है वह इसे मददगार पाता है।

आप एक प्रॉक्सी का उपयोग करके देख सकते हैं (यह ECMAScript 2015 के बाद से मानक है): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy

latLngLiteral = new Proxy({},{
    set: function(obj, prop, val) {
        //only these two properties can be set
        if(['lng','lat'].indexOf(prop) == -1) {
            throw new ReferenceError('Key must be "lat" or "lng"!');
        }

        //the dec format only accepts numbers
        if(typeof val !== 'number') {
            throw new TypeError('Value must be numeric');
        }

        //latitude is in range between 0 and 90
        if(prop == 'lat'  && !(0 < val && val < 90)) {
            throw new RangeError('Position is out of range!');
        }
        //longitude is in range between 0 and 180
        else if(prop == 'lng' && !(0 < val && val < 180)) {
            throw new RangeError('Position is out of range!');
        }

        obj[prop] = val;

        return true;
    }
});

तब आप आसानी से कह सकते हैं:

myMap = {}
myMap.position = latLngLiteral;

5

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

टाइपस्क्रिप्ट में आपका इंटरफ़ेस जैसा दिख सकता है:

interface IMyInterface {
    id: number; // TypeScript types are lowercase
    name: string;
    callback: (key: string; value: any; array: string[]) => void;
    type: "test" | "notATest"; // so called "union type"
}

आप क्या नहीं कर सकते:


3

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

आप यहाँ आरोपण देख सकते हैं


2

जावास्क्रिप्ट में इंटरफेस नहीं है। लेकिन इसे डक-टाइप किया जा सकता है, एक उदाहरण यहां पाया जा सकता है:

http://reinsbrain.blogspot.com/2008/10/interface-in-javascript.html


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

1
मुझे ट्रांसप्लिंग (और डिबगिंग के लिए स्रोत मानचित्र) से नफरत है, लेकिन टाइपस्क्रिप्ट ES6 के इतने करीब है कि मैं अपनी नाक को पकड़ने और टाइपस्क्रिप्ट में गोता लगाने के लिए इच्छुक हूं। ES6 / टाइपस्क्रिप्ट दिलचस्प है क्योंकि यह आपको इंटरफ़ेस (व्यवहार) को परिभाषित करते समय विधियों के अतिरिक्त गुणों को शामिल करने की अनुमति देता है।
पुनर्वसु

1

मुझे पता है कि यह एक पुराना है, लेकिन मैंने हाल ही में खुद को इंटरफेस के खिलाफ वस्तुओं की जांच के लिए एक आसान एपीआई की आवश्यकता है। तो मैंने यह लिखा: https://github.com/tomhicks/methodical

यह एनपीएम के माध्यम से भी उपलब्ध है: npm install methodical

यह मूल रूप से ऊपर बताई गई हर चीज को करता है, जिसमें कुछ विकल्प थोड़े अधिक सख्त होते हैं, और सभी बिना if (typeof x.method === 'function')बॉयलरप्लेट के लोड के होते हैं ।

उम्मीद है कि कोई इसे उपयोगी पाता है।


टॉम, मैंने अभी एक AngularJS TDD वीडियो देखा और जब वह एक फ्रेमवर्क स्थापित करता है, तो आश्रित पैकेजों में से एक आपका मैथोडिकल पैकेज होता है! बहुत बढ़िया!
कोडी

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

तुम शर्त लगाओ, टॉम। मैं जल्द ही इसे खोजने की कोशिश करूंगा। प्रॉक्स के रूप में इंटरफेस के बारे में एक किस्सा भी। चीयर्स!
कोड़ी

1

यह एक पुराना प्रश्न है, फिर भी यह विषय मुझे ख़राब करना नहीं चाहता।

इंटरफ़ेस को "लागू करने" पर वेब पर और यहाँ के कई जवाबों के अनुसार, मैं एक वैकल्पिक दृश्य सुझाना चाहूंगा:

मैं इंटरफेस की कमी महसूस हो रहा है सबसे जब मैं कई वर्गों है कि व्यवहार इसी तरह (यानी उपयोग कर रहा हूँ एक इंटरफ़ेस को लागू )।

उदाहरण के लिए, मेरे पास एक ईमेल जनरेटर है जो ईमेल अनुभागों को प्राप्त करने की अपेक्षा करता है , जो कि अनुभागों की सामग्री और HTML उत्पन्न करने के लिए "पता" करता है। इसलिए, उन सभी को कुछ प्रकार getContent(id)और getHtml(content)विधियों की आवश्यकता होती है।

इंटरफेस के निकटतम पैटर्न (यद्यपि यह अभी भी एक हल है) मैं सोच सकता था कि एक वर्ग का उपयोग कर रहा हूँ जिसे 2 तर्क मिलेंगे, जो 2 इंटरफ़ेस विधियों को परिभाषित करेगा।

इस पैटर्न के साथ मुख्य चुनौती यह है कि staticइसके गुणों को एक्सेस करने के लिए तरीकों को या तो तर्क के रूप में प्राप्त करना है या उदाहरण के रूप में खुद को तर्क देना है। हालांकि ऐसे मामले हैं जिनमें मुझे यह ट्रेड-ऑफ परेशानी के लायक लगता है।

class Filterable {
  constructor(data, { filter, toString }) {
    this.data = data;
    this.filter = filter;
    this.toString = toString;
    // You can also enforce here an Iterable interface, for example,
    // which feels much more natural than having an external check
  }
}

const evenNumbersList = new Filterable(
  [1, 2, 3, 4, 5, 6], {
    filter: (lst) => {
      const evenElements = lst.data.filter(x => x % 2 === 0);
      lst.data = evenElements;
    },
    toString: lst => `< ${lst.data.toString()} >`,
  }
);

console.log('The whole list:    ', evenNumbersList.toString(evenNumbersList));
evenNumbersList.filter(evenNumbersList);
console.log('The filtered list: ', evenNumbersList.toString(evenNumbersList));


0

अमूर्त इंटरफ़ेस इस तरह

const MyInterface = {
  serialize: () => {throw "must implement serialize for MyInterface types"},
  print: () => console.log(this.serialize())
}

एक उदाहरण बनाएँ:

function MyType() {
  this.serialize = () => "serialized "
}
MyType.prototype = MyInterface

और इसका उपयोग करें

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