461 Stimmen

Verfügt JavaScript über einen Schnittstellentyp (wie z. B. Java's 'interface')?

Ich lerne wie man OOP mit JavaScript macht . Verfügt es über ein Schnittstellenkonzept (wie das von Java interface ) ?

Ich könnte also einen Hörer erstellen...

11voto

shaedrich Punkte 4845

Ich hoffe, dass es für alle, die noch nach einer Antwort suchen, hilfreich ist.

Sie können die Verwendung eines Proxys ausprobieren (seit ECMAScript 2015 ist dies Standard): 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;
    }
});

Dann können Sie leicht sagen:

myMap = {}
myMap.position = latLngLiteral;

Wenn Sie sich über instanceof (gefragt von @Kamaffeather), können Sie es in ein Objekt wie folgt verpacken:

class LatLngLiteral {
    constructor(props)
    {
        this.proxy = new Proxy(this, {
            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;
            }
        })
        return this.proxy
    }
}

Dies kann ohne Verwendung von Proxy sondern stattdessen die Klassen Getter y Einsteller :

class LatLngLiteral {
    #latitude;
    #longitude;

    get lat()
    {
        return this.#latitude;
    }

    get lng()
    {
        return this.#longitude;
    }

    set lat(val)
    {
        //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(!(0 < val && val < 90)) {
            throw new RangeError('Position is out of range!');
        }

        this.#latitude = val
    }

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

        //longitude is in range between 0 and 180
        if(!(0 < val && val < 180)) {
            throw new RangeError('Position is out of range!');
        }

        this.#longitude = val
    }
}

8voto

Alex Reitbort Punkte 13255

In Java braucht man Schnittstellen, da es statisch typisiert ist und der Vertrag zwischen Klassen während der Kompilierung bekannt sein sollte. In JavaScript ist das anders. JavaScript ist dynamisch typisiert, d. h., wenn Sie das Objekt erhalten, können Sie einfach prüfen, ob es eine bestimmte Methode hat, und diese aufrufen.

5voto

shaedrich Punkte 4845

Wenn Sie einen Transcompiler verwenden möchten, können Sie TypeScript ausprobieren. Es unterstützt den Entwurf der ECMA-Funktionen (im Vorschlag werden Schnittstellen als " Protokolle "), ähnlich wie es Sprachen wie coffeescript oder babel tun.

In TypeScript kann Ihre Schnittstelle wie folgt aussehen:

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"
}

Was Sie nicht tun können:

4voto

Gilbert Punkte 1501

Versuchen Sie dies: Beschreiben Sie die Schnittstelle als Klasse und verwenden Sie @implements JSDoc, um zu zeigen, dass eine bestimmte Klasse die definierte Schnittstelle implementiert. Sie sehen rote, verschnörkelte Linien am Klassennamen, wenn die Klasse einige Eigenschaften nicht implementiert. Ich habe mit VSCode getestet.

// @ts-check

// describe interface using a class
class PlainInterface {
    size = 4;
    describe() {}
    show(){ }
}

/**
 * @implements  PlainInterface 
 */
class ConcretePlain {
    size = 4;
    describe() {
        console.log('I am described')
    }
    show(){
        console.log('I am shown')
    }
}       

const conc = new ConcretePlain();
conc.describe();

4voto

Mit einer Schnittstelle können Sie eine Art von Polymorphismus implementieren. Javascript macht NICHT brauchen den Schnittstellentyp, um diese und andere interface Sachen. Und warum? Javascript ist eine dynamisch typisierte Sprache. Nehmen Sie als Beispiel eine Reihe von Klassen, die die gleichen Methoden haben:

Circle()
Square()
Triangle()

Wenn Sie wissen wollen, wie Polymorphismus funktioniert, ist das Buch MFC von David Kruglinsky großartig (geschrieben für C++)

Implementieren Sie in diesen Klassen die Methode draw() schieben Sie die Instanzen dieser Klassen in das Array und rufen die draw() Methoden in einer Schleife, die das Array iteriert. Das ist vollkommen gültig. Man könnte sagen, Sie implementieren implizit eine abstract class . In der Realität ist es nicht da, aber in deinem Kopf hast du es getan und Javascript hat kein Problem damit. Der Unterschied zu einer echten Schnittstelle ist, dass Sie HAVE alle Methoden der Schnittstelle zu implementieren, und das ist in diesem Fall nicht erforderlich.

Eine Schnittstelle ist ein Vertrag. Sie müssen alle Methoden implementieren. Nur wenn man es statisch macht, muss man das tun.

Es ist fragwürdig, eine Sprache wie Javascript von dynamisch auf statisch umzustellen. Es ist nicht geeignet, statisch zu sein. Erfahrene Entwickler haben keine Probleme mit der dynamischen Natur von Javascript.

Der Grund für die Verwendung von Typescript ist mir also nicht klar. Wenn Sie NodeJS zusammen mit Javascript verwenden, können Sie extrem effiziente und kostengünstige Unternehmenswebsites erstellen. Die Kombination aus Javascript, NodeJS und MongoDB ist bereits ein großer Gewinn.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X