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...
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...
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
}
}
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.
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:
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();
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 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.