In JavaScript, an interface refers to a reference type that defines a contract. The interface actually tells us what methods a class implements, thereby helping it use this class; the interface can make the code more stable.
The operating environment of this tutorial: windows7 system, javascript version 1.8.5, Dell G3 computer.
There is no built-in way to create or implement interfaces in JavaScript. It also has no built-in method for determining whether one object implements the same set of methods as another object. This makes it difficult to use objects interchangeably. But JavaScript is very flexible, and we can implement it in other ways.
The interface actually defines what methods should be in the object. He does not need to consider how these methods are implemented, but defines that the object has these methods.
Interface refers to the reference type that defines the agreement. Other types implement interfaces to ensure that they support certain operations. An interface specifies the members that must be provided by a class or other interface that implements it. Similar to classes, interfaces can contain methods, properties, indexers, and events as members.
Interfaces actually tell us which methods a class implements. This helps them use this class. Interfaces can make our code more stable if we add a method to the interface. If a class that implements it does not add this method accordingly, it will definitely throw an error.
There are three methods for JavaScript imitation interface:
Commentation method
Attribute checking method
Duck transformation method
Using comments to describe the interface is the simplest method, but the effect is the worst.
/* interface Composite { function add(child); function remove(child); function getChild(index); } interface FormItem { function save(); } */ class CompositeForm { add(child) { //... } remove(child) { } getChild(index) { //... } save() { //... } }
This imitation method is not very good. It does not check whether CompositeForm implements the method correctly. It is entirely through programmers consciously implementing the interface in the annotation. However, this implementation is very simple, but it does not help in testing and debugging.
This method is more cautious, but the interface is also written in the form of comments, but you can know a certain class by checking an attribute What interface does it claim to implement?
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());
The advantage of this method is that it provides documentation for the interface implemented by the class. If the required interface is not among the interfaces that my class declares to support (that is, it is not in my this.implementsInterface) ), you will see an error message.
The shortcomings are also obvious. If the interface declared in my this.implementsInterface is different from the interface defined in my comments but the check can still pass, it means that calling the addForm method will not cause an error.
In fact, it doesn’t matter whether a class declares which interfaces it supports, as long as it has the methods in these interfaces. Duck transformation uses the method set of an object as the only criterion for judging whether it is an instance. The implementation principle is also very simple: if an object has a method with the same name as the method defined by the interface, then it can be considered that it implements the interface.
// 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); }
I did not implement the save method in the CompositeForm class in the above code. Running this code will result in an error.
But the duck transformation method also has shortcomings, and all inspection aspects are mandatory.
I used class inheritance to simulate the interface. Please see the code for the specific implementation.
First we define a class used as an interface. The attribute method represents the method set of the interface.
class Interface { constructor() { this.mehods = ['add', 'save', 'remove', 'save']; } static ensureImplements(obj) { //... } }
Define a CompositeForm class to inherit this interface, and call the ensureImplements method of the parent class in the class to detect Interface
class CompositeForm extends Interface{ constructor() { super().ensureImplements(this); } }
Improve the ensureImplements method
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); } } } }
[Recommended learning: javascript advanced tutorial】
The above is the detailed content of What is an interface in javascript. For more information, please follow other related articles on the PHP Chinese website!