In JavaScript bezieht sich eine Schnittstelle auf einen Referenztyp, der einen Vertrag definiert. Die Schnittstelle teilt uns tatsächlich mit, welche Methoden eine Klasse implementiert, wodurch die Verwendung dieser Klassenschnittstellen den Code stabiler machen kann.
Die Betriebsumgebung dieses Tutorials: Windows 7-System, JavaScript-Version 1.8.5, Dell G3-Computer.
Es gibt keine integrierte Möglichkeit, Schnittstellen in JavaScript zu erstellen oder zu implementieren. Es verfügt auch nicht über eine integrierte Methode zur Bestimmung, ob ein Objekt denselben Methodensatz implementiert wie ein anderes Objekt. Dies macht es schwierig, Objekte austauschbar zu verwenden. Aber JavaScript ist sehr flexibel und wir können es auf andere Weise implementieren.
Die Schnittstelle definiert tatsächlich, welche Methoden in einem Objekt enthalten sein sollten. Er muss nicht berücksichtigen, wie diese Methoden implementiert werden, sondern definiert, dass das Objekt über diese Methoden verfügt.
Interface bezieht sich auf einen Referenztyp, der einen Vertrag definiert. Andere Typen implementieren Schnittstellen, um sicherzustellen, dass sie bestimmte Vorgänge unterstützen. Eine Schnittstelle gibt die Mitglieder an, die von einer Klasse oder einer anderen Schnittstelle bereitgestellt werden müssen, die sie implementiert. Ähnlich wie Klassen können Schnittstellen Methoden, Eigenschaften, Indexer und Ereignisse als Mitglieder enthalten.
Schnittstellen sagen uns tatsächlich, welche Methoden eine Klasse implementiert. Dies hilft ihnen bei der Nutzung dieser Klasse. Schnittstellen können unseren Code stabiler machen, wenn wir der Schnittstelle eine Methode hinzufügen. Wenn eine Klasse, die sie implementiert, diese Methode nicht entsprechend hinzufügt, wird definitiv ein Fehler ausgegeben.
Es gibt drei Methoden für die JavaScript-Imitationsschnittstelle:
Annotationsmethode
Attributprüfungsmethode
Duck-Transformationsmethode
Die Verwendung von Kommentaren zur Beschreibung der Schnittstelle ist die einfachste Methode, aber die Wirkung ist am schlimmsten.
/* interface Composite { function add(child); function remove(child); function getChild(index); } interface FormItem { function save(); } */ class CompositeForm { add(child) { //... } remove(child) { } getChild(index) { //... } save() { //... } }
Diese Nachahmungsmethode ist nicht sehr gut. Sie prüft nicht, ob CompositeForm die Methode korrekt implementiert. Dies geschieht ausschließlich durch die bewusste Implementierung der Schnittstelle in der Annotation. Diese Implementierung ist zwar sehr einfach, hilft aber beim Testen und Debuggen nicht.
Diese Methode ist vorsichtiger, aber die Schnittstelle wird auch in Form von Kommentaren geschrieben. Sie können nur wissen, welche Schnittstelle eine bestimmte Klasse implementieren soll, indem Sie ein Attribut überprüfen.
class CompositeForm { constructor() { this.implementsInterface = ['Composite', 'FormItem']; } } function addForm(formInstance) { if (!implements(formInstance, 'Composite', 'FormItem')) { throw new Error('对象没有实现接口方法'); } } function implements(obj) { // 这个方法查询接口 for (let i = 1; i < arguments.length; i++) { let interfaceName = arguments[i]; let interfaceFound = false; for (let j = 1; j < obj.implementsInterface.length; j++) { if (obj.implementsInterface[j] == interfaceName) { interfaceFound = true; break; } } if (!interfaceFound) { return false; } return true; } } addForm(new CompositeForm());
Der Vorteil dieser Methode besteht darin, dass sie Dokumentation für die von der Klasse implementierte Schnittstelle bereitstellt. Wenn die erforderliche Schnittstelle nicht zu den Schnittstellen gehört, die meine Klasse angeblich unterstützt (das heißt, sie ist nicht in meinem this.implementsInterface enthalten), Sie können eine Fehlermeldung sehen.
Die Mängel sind ebenfalls offensichtlich. Wenn sich die in meiner this.implementsInterface deklarierte Schnittstelle von der in meiner Annotation definierten Schnittstelle unterscheidet, die Prüfung jedoch trotzdem bestanden werden kann, bedeutet dies, dass der Aufruf der addForm-Methode nicht explodiert.
Tatsächlich spielt es keine Rolle, ob eine Klasse deklariert, welche Schnittstellen sie unterstützt, solange sie über die Methoden in diesen Schnittstellen verfügt. Die Duck-Transformation verwendet den Methodensatz eines Objekts als einziges Kriterium für die Beurteilung, ob es sich um eine Instanz handelt. Das Implementierungsprinzip ist ebenfalls sehr einfach: Wenn ein Objekt eine Methode mit demselben Namen wie die durch die Schnittstelle definierte Methode hat, kann davon ausgegangen werden, dass es die Schnittstelle implementiert.
// interface class Interface { constructor(name, method) { if (arguments.length != 2) { throw new Error('两个参数:name method'); } this.name = name; this.method = []; for (let i in method) { if (typeof method[i] != 'string') { throw new Error('method 必须是字符串'); } this.method.push(method[i]); } } //检查接口方法 static ensureImplements(obj) { if (arguments.length < 2) { throw new Error('参数小于两个'); } for (let i = 1; i < arguments.length; i++) { var instanceInterface = arguments[i]; if (instanceInterface.constructor !== Interface) { throw new Error('你要检查的参数不属于Interface接口') } for (let j in instanceInterface.method) { let methodName = instanceInterface.method[j]; if (!obj[methodName] || typeof obj[methodName] !== 'function') { throw new Error(`请实现接口的${methodName}方法`) } } } } } // 实例化接口对象 var Composite = new Interface('Composite', ['add', 'remove', 'getChild']); var FormItem = new Interface('FormItem', ['save']); // CompositeForm 类 class CompositeForm { //... add() {} remove() {} getChild() {} } let c1 = new CompositeForm(); Interface.ensureImplements(c1, Composite, FormItem); function addForm(formInterface) { ensureImplements(formInterface, Composite, FormItem); }
Ich habe die Speichermethode in der CompositeForm-Klasse im obigen Code nicht implementiert. Das Ausführen dieses Codes führt zu einem Fehler.
Allerdings weist die Entenverformungsmethode auch Mängel auf und alle Inspektionsaspekte sind obligatorisch.
Ich habe die Klassenvererbung verwendet, um die Schnittstelle zu simulieren. Die spezifische Implementierung finden Sie im Code.
Zuerst definieren wir eine Klasse, die als Schnittstelle verwendet wird. Die Attributmethode stellt den Methodensatz der Schnittstelle dar.
class Interface { constructor() { this.mehods = ['add', 'save', 'remove', 'save']; } static ensureImplements(obj) { //... } }
Definieren Sie eine CompositeForm-Klasse, um diese Schnittstelle zu erben, und rufen Sie die secureImplements-Methode der übergeordneten Klasse in der Klasse auf, um die Schnittstelle zu erkennen
class CompositeForm extends Interface{ constructor() { super().ensureImplements(this); } }
Perfektionieren Sie die „sureImplements“-Methode
class Interface { constructor() { this.mehods = ['add', 'save', 'remove', 'save']; } static ensureImplements(obj) { for (let i in this.mehods) { let methodName = this.mehods[i] if (!obj[methodName] || typeof obj[methodName] !== 'function') { let err = '请实现接口' + methodName + '的方法'; throw new Error(err); } } } }
【Empfohlenes Lernen: Javascript-Tutorial für Fortgeschrittene】
Das obige ist der detaillierte Inhalt vonWas ist eine Schnittstelle in Javascript?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!