search
HomeWeb Front-endJS TutorialObject-oriented Javascript Part 2 (Introduction to interface implementation)_js object-oriented

It is enough to show how important interfaces are in the object-oriented field. But JS does not have a built-in interface mechanism like other high-level object-oriented languages ​​(C#, Java, C, etc.) to determine that one set of objects contains similar characteristics to another set of objects. Fortunately, JS has great flexibility (which I talked about above), which makes it very simple to imitate interface features. So what exactly is an interface?

Interface provides unified method definitions between some classes with similar behavior (may be of the same type or different types), so that these classes can communicate well.

What are the benefits of using interfaces? Simply put, it can improve the reusability of similar modules in the system and make different types of communications more robust. Once an interface is implemented, all methods in the interface must be implemented. For large-scale Web projects, multiple complex modules with similar functional modules only need to provide an interface to provide an implementation without affecting each other. But we must be clear that interfaces are not omnipotent. Since JS is a weakly typed language, you cannot force other team members to strictly follow the interfaces you provide, but you can use code specifications and auxiliary classes to alleviate this problem. In addition, it will also have a certain impact on system performance, which should be determined according to the complexity of your system requirements. Since there are no built-in interface and implements keywords, let's take a look at how JS imitates and implements interfaces.

1. The simplest and least effective way to implement an interface is to use annotations. That is, use interface in comments to explain the intent of the interface.

Copy code The code is as follows:

/*
interface Composite {
function add(child);
function remove(child);
function getChild(index);
}
interface FormItem {
funtion save();
}
*/
var CompositeForm = function(id, name, action) {
// implements Composite, FormItem
}
CompositeForm.prototype = {
// implements Composite interface
add: function (child) {
//...
},
remove: function(child) {
//...
},
getChild: function(index) {
//...
}
// implements FormItem interface
save: function() {
//...
}
}

This does not do a good job of simulating the functionality of the interface and ensuring that the Composite class actually implements the set of methods. It does not throw an error to notify the programmer of the problem. It has no effect other than explanation. All consistency is required. Programmers do it voluntarily. But it is easy to implement, does not require additional classes or functions, does not affect the size and execution speed of the document, and comments can be easily stripped, which improves reusability to a certain extent, because the description of the class provided can be the same as other implementations Interface classes communicate.

2. Check the mock interface with properties. The class explicitly declares the interface to be implemented, and checks whether the corresponding interface is implemented through attributes.
Copy code The code is as follows:

/*
interface Composite {
function add(child);
function remove(child);
function getChild(index);
}
interface FormItem {
funtion save();
}
*/
var CompositeForm = function(id, name, action) {
this.implementsInterfaces = ["Composite", "FormItem"];
//...
}
function checkInterfaces( formInstance) {
if(!implements(formInstance, "Composite", "FormItem")) {
throw new Error("Object doesn't implement required interface.");
}
/ /...
}
//check to see if an instance object declares that it implements the required interface
function implements(instance) {
for(var i = 1; i var interfaceName = arguments[i];
var isFound = false;
for(var j = 0; j if(interfaceName == instance.implementsInterfaces[j]) {
isFound = true;
break;
}
}
if(!isFound) return false;// An interface was not found.
}
return true;// All interfaces were found.
}

Found here, comments still added to illustrate the interface. However, an attribute implementsInterfaces is added to the Composite class to indicate which interfaces the class must implement. Check this property to determine whether the corresponding interface is implemented. If it is not implemented, an error will be thrown. But the disadvantage is that you still can't judge whether the corresponding interface method is actually implemented. You just "claim" to have implemented the interface, which also increases the corresponding workload.

3. Use "duck pattern recognition" to implement the interface. It does not matter whether a class supports the implemented interface from the property inspection implementation. As long as all the methods in the interface appear in the corresponding places in the class, it is enough to indicate that the interface has been implemented. Just like "If it walks like a duck and quacks like a duck, no matter whether it has a label saying it is a duck or not, then we think it is a duck." Use auxiliary classes to determine whether a class exists (implements) all the methods in the corresponding interface. If it does not exist, it means that it is not implemented.
Copy code The code is as follows:

// Interfaces
var Composite = new Interface( "Composite", ["add", "remove", "getChild"]);
var FormItem = new Interface("FormItem", ["save"]);

var CompositeForm = function( id, name, action) {
// implements Composite, FormItem interfaces
}
function checkInterfaces(formInstance) {
Interface.ensureImplements(formInstance, "Composite", "FormItem");
//...
}

Interface class
Copy code The code is as follows:

// Interface class is for checking if an instance object implements all methods of required interface
var Interface = function(name, methods) {
if(arguments.length != 2 ) {
throw new Error("Interface constructor expects 2 arguments, but exactly provided for " arguments.length " arguments.");
}
this.name = name;
this.methods = [];
for(var i = 0;i if(typeof methods[i] != "string") {
throw new Error("Interface constructor expects to pass a string method name.");
}
this.methods.push(methods[i]);
}
}
//static class method
Interface .ensureImplements = function(instance) {
if(arguments.length throw new Error("Function Interface.ensureImplements expects at least 2 arguments, but exactly passed for " arguments.length " arguments. ");
}
for(var i = 1, len = arguments.length; i var interface = arguments[i];
if(interface.constructor != Interface) {
throw new Error("Function Interface.ensureImplements expects at least 2 arguments to be instances of Interface.");
}
for(var j = 0, mLen = interface.methods .length; j var method = interface.methods[j];
if(!instance[method] || typeof instance[method] != "function") {
throw new Error("Function Interface.ensureImplements: object doesn't implements " interface.name ". Method " method " wasn't found.");
}
}
}
}

Strict type checking is not always necessary, and the above interface mechanism is rarely used in normal web front-end development. But when you face a complex system, especially one with many similar modules, interface-oriented programming will become very important. It seems to reduce the flexibility of JS, but in fact it improves the flexibility of classes and reduces the coupling between classes, because when you pass in any object that implements the same interface, it can be parsed correctly. So when is it appropriate to use interfaces? For a large-scale project, there must be many team members, and the project will be split into more fine-grained functional modules. In order to ensure the progress, a "placeholder program" (interface) must be used in advance to explain the function of the module or to be related to the developed module. When communicating between completed modules, it is necessary to provide a unified interface (API). As the project continues to advance, the requirements may continue to change, and the functions of each module will also change accordingly. However, the communication between each other and the API provided to the upper modules will always remain unchanged, ensuring the stability and durability of the entire architecture. sex. Below we use a specific example to illustrate the practical application of the interface. Assume that a class is designed to automatically detect the result object (TestResult class) and format it to output a web page view without using the interface implementation:
Copy code The code is as follows:

var ResultFormatter = function(resultObject) {
if(!(resultObject instanceof TestResult)) {
throw new Error("ResultFormatter 생성자는 TestResult의 인스턴스를 예상합니다.");
this.resultObject = resultObject;
}
ResultFormatter.prototype.render = function() {
var date = this.resultObject.getDate()
var items = this.resultObject. getResults();
var 컨테이너 = document.createElement("div");
var header = document.createElement("h3")

header.innerHTML = "" 날짜 .toUTCString();
container.appendChild(header);
var list = document.createElement("ul");
container.appendChild(list)

for(var i = 0, len = items.length; i ) {
var item = document.createElement("li")
item.innerHTML = items[i]
list.appendChild(item); 🎜>}
return 컨테이너;
}


우선 ResultFormatter 클래스의 생성자는 TestResult 인스턴스인지 여부만 확인하지만 getDate 메소드가 해당 인스턴스인지 여부는 보장하지 않습니다. ()가 렌더링되고 getResults()가 구현됩니다. 또한 요구 사항이 계속 변경됨에 따라 이제 getDate() 및 getResults() 메서드를 포함하는 Weather 클래스가 있지만 TestResult의 인스턴스인지 여부만 확인할 수 있기 때문에 render 메서드를 실행할 수 없습니다. 말이 너무 없네? 해결책은 수표 인스턴스를 제거하고 인터페이스로 교체하는 것입니다.


//ResultSet 인터페이스 생성
var ResultSet = new Interface("ResultSet", ["getDate", "getResults"]);
var ResultFormatter = function(resultObject) {
// Interface.ensureImplements를 사용하여 resultObject 확인
인터페이스. verifyImplements(resultObject , ResultSet);
this.resultObject = resultObject;
}
ResultFormatter.prototype.render = function() {
// 이전과 동일하게 유지
var date = this .resultObject.getDate();
var items = this.resultObject.getResults();
var 컨테이너 = document.createElement("div")
var header = document.createElement("h3") ;

header.innerHTML = "date.toUTCString()"의 테스트 결과
container.appendChild(header)
var list = document.createElement("ul"); 컨테이너.appendChild(목록);

for(var i = 0, len = items.length; i ) {
var item = document.createElement("li")
item.innerHTML = items[ i];
list.appendChild(item);
}
return 컨테이너
}


렌더링 방법이 변경되지 않은 것을 볼 수 있습니다. 어떤 식으로든. 변경된 것은 인터페이스를 추가하고 유형 확인을 위해 인터페이스를 사용하는 것뿐이었습니다. 동시에 이제 Weather 클래스의 인스턴스를 전달하여 호출할 수 있습니다. 물론 ResultSet 인터페이스를 구현하는 모든 클래스의 인스턴스를 전달하여 검사를 더욱 정확하고 관대하게 만들 수도 있습니다. 이후 JS 디자인 패턴이 도입되면서 인터페이스는 팩토리 모드, 조합 모드, 데코레이션 모드 및 명령 모드에서 널리 사용됩니다. 인터페이스가 JS 모듈식 디자인에 가져오는 이점을 모두가 즐길 수 있기를 바랍니다.
Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
JavaScript Engines: Comparing ImplementationsJavaScript Engines: Comparing ImplementationsApr 13, 2025 am 12:05 AM

Different JavaScript engines have different effects when parsing and executing JavaScript code, because the implementation principles and optimization strategies of each engine differ. 1. Lexical analysis: convert source code into lexical unit. 2. Grammar analysis: Generate an abstract syntax tree. 3. Optimization and compilation: Generate machine code through the JIT compiler. 4. Execute: Run the machine code. V8 engine optimizes through instant compilation and hidden class, SpiderMonkey uses a type inference system, resulting in different performance performance on the same code.

Beyond the Browser: JavaScript in the Real WorldBeyond the Browser: JavaScript in the Real WorldApr 12, 2025 am 12:06 AM

JavaScript's applications in the real world include server-side programming, mobile application development and Internet of Things control: 1. Server-side programming is realized through Node.js, suitable for high concurrent request processing. 2. Mobile application development is carried out through ReactNative and supports cross-platform deployment. 3. Used for IoT device control through Johnny-Five library, suitable for hardware interaction.

Building a Multi-Tenant SaaS Application with Next.js (Backend Integration)Building a Multi-Tenant SaaS Application with Next.js (Backend Integration)Apr 11, 2025 am 08:23 AM

I built a functional multi-tenant SaaS application (an EdTech app) with your everyday tech tool and you can do the same. First, what’s a multi-tenant SaaS application? Multi-tenant SaaS applications let you serve multiple customers from a sing

How to Build a Multi-Tenant SaaS Application with Next.js (Frontend Integration)How to Build a Multi-Tenant SaaS Application with Next.js (Frontend Integration)Apr 11, 2025 am 08:22 AM

This article demonstrates frontend integration with a backend secured by Permit, building a functional EdTech SaaS application using Next.js. The frontend fetches user permissions to control UI visibility and ensures API requests adhere to role-base

JavaScript: Exploring the Versatility of a Web LanguageJavaScript: Exploring the Versatility of a Web LanguageApr 11, 2025 am 12:01 AM

JavaScript is the core language of modern web development and is widely used for its diversity and flexibility. 1) Front-end development: build dynamic web pages and single-page applications through DOM operations and modern frameworks (such as React, Vue.js, Angular). 2) Server-side development: Node.js uses a non-blocking I/O model to handle high concurrency and real-time applications. 3) Mobile and desktop application development: cross-platform development is realized through ReactNative and Electron to improve development efficiency.

The Evolution of JavaScript: Current Trends and Future ProspectsThe Evolution of JavaScript: Current Trends and Future ProspectsApr 10, 2025 am 09:33 AM

The latest trends in JavaScript include the rise of TypeScript, the popularity of modern frameworks and libraries, and the application of WebAssembly. Future prospects cover more powerful type systems, the development of server-side JavaScript, the expansion of artificial intelligence and machine learning, and the potential of IoT and edge computing.

Demystifying JavaScript: What It Does and Why It MattersDemystifying JavaScript: What It Does and Why It MattersApr 09, 2025 am 12:07 AM

JavaScript is the cornerstone of modern web development, and its main functions include event-driven programming, dynamic content generation and asynchronous programming. 1) Event-driven programming allows web pages to change dynamically according to user operations. 2) Dynamic content generation allows page content to be adjusted according to conditions. 3) Asynchronous programming ensures that the user interface is not blocked. JavaScript is widely used in web interaction, single-page application and server-side development, greatly improving the flexibility of user experience and cross-platform development.

Is Python or JavaScript better?Is Python or JavaScript better?Apr 06, 2025 am 12:14 AM

Python is more suitable for data science and machine learning, while JavaScript is more suitable for front-end and full-stack development. 1. Python is known for its concise syntax and rich library ecosystem, and is suitable for data analysis and web development. 2. JavaScript is the core of front-end development. Node.js supports server-side programming and is suitable for full-stack development.

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
3 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Best Graphic Settings
3 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. How to Fix Audio if You Can't Hear Anyone
3 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: How To Unlock Everything In MyRise
4 weeks agoBy尊渡假赌尊渡假赌尊渡假赌

Hot Tools

MantisBT

MantisBT

Mantis is an easy-to-deploy web-based defect tracking tool designed to aid in product defect tracking. It requires PHP, MySQL and a web server. Check out our demo and hosting services.

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

This project is in the process of being migrated to osdn.net/projects/mingw, you can continue to follow us there. MinGW: A native Windows port of the GNU Compiler Collection (GCC), freely distributable import libraries and header files for building native Windows applications; includes extensions to the MSVC runtime to support C99 functionality. All MinGW software can run on 64-bit Windows platforms.

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

Powerful PHP integrated development environment

EditPlus Chinese cracked version

EditPlus Chinese cracked version

Small size, syntax highlighting, does not support code prompt function

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment