Dieses Mal erkläre ich Ihnen ausführlich die Schritte zur Verwendung von Schnittstellen in JS. Was sind die Vorsichtsmaßnahmen für die Verwendung von Schnittstellen in JS?
Dies ist die README-Datei von js-interface. Obwohl es keine sehr komplizierte Sache ist, werde ich die Quellcode-Ideen ORZ aufschreiben
Wenn ich an einem Projekt mit separater Vorder- und Rückseite arbeite, habe ich beim Lesen des Buches „JavaScript Design Patterns“, Kapitel 2, einige Kopfschmerzen erwähnte, dass in Das Konzept der Simulation von Schnittstellen (Schnittstelle) in JavaScript die Verwendung vieler Entwurfsmuster erleichtert, daher habe ich versucht, eine Schnittstelle zu simulieren. Da ich ein Backend-Java-Entwickler bin, hoffe ich, Schnittstellenstandardimplementierung, Schnittstellenvererbung, zu dieser Simulationsschichtmethode hinzuzufügen Überladen von und anderen Funktionen, obwohl das Hinzufügen dieser Dinge unweigerlich die Leistung beeinträchtigen wird, kann es für mich einige Entwicklungserfahrungen verbessern (ich kenne TypeScript, wollte mir nur ein Rad zulegen und es ausprobieren: P).
Da die ursprüngliche Absicht darin besteht, die Verwaltung von API zu erleichtern, erstellen Sie eine Demo über API.
const config = { // 接口的名字 name: 'IApi', // 是否打开此接口的 debug 开关 // 开发时必须打开,否则不会启动 (方法声明、方法实现等)入参的类型检查。 // 打开这个的情况下,还会获得一些调试用的信息。 debug: true, } let IApi = new Interface(config)
Der einfachste Weg zum Deklarieren:
IApi.method({name: 'getName'}) // 等价于 IApi.method({name: 'getName', args: undefined})
Dies deklariert, dass die IApi
-Schnittstelle eine Methode, sie hat keine Parameter und keine Standardimplementierung, was erfordert, dass jede nachfolgende getName
-Subschnittstelle oder Implementierungsklasse diese Methode implementieren muss, andernfalls wird eine Ausnahme ausgelöst. IApi
IApi.method({ name: 'getName', args: null })
Achtung!
Wenn es args
ist, bedeutet dies, dass die Methode eine beliebige Anzahl von Parametern akzeptieren kann. Wenn eine Methode überladen ist (Einzelheiten finden Sie in der Beschreibung der Überladung später): null
// 声明一个空参方法 IApi.method({ id: 0, name: 'getName', args: null }) // 重载上面的方法,使其有且只有一个 'string' 类型,名为 name 的参数 IApi.method({ id: 1, name: 'getName', args: [ {name: 'name', type: 'string', support: val => typeof val === 'string'} ] })
Achtung!
In der Parameterbeschreibung ist das-Attribut type
nur ein String-Wert, der nicht wirklich den tatsächlichen Typ des Parameters darstellt. Wie das Attribut stellt es nur Informationen zum Debuggen bereit, sodass Sie jeden Zeichenfolgenwert eingeben können, der Ihrer Meinung nach angemessen genug ist, um den Parameter mit einigen Informationen zu kennzeichnen. name
-Attribut. Wenn es support
zurückgibt, wird der nächste Parameter überprüft, bis alle Parameter überprüft wurden oder ein Parameter an einer bestimmten Position nicht akzeptiert wird . true
durchführen, z. B. das Konvertieren von Objekten, das Überprüfen bestimmter Attribute usw. support
IApi.method({ name: 'getName', // 默认实现,不能为箭头函数! implement: function() { return "IApi" } })
// 声明两个方法,它们都没有参数,也不需要重载因此这样就可以了 IApi .method({ name: 'getName' }) // 项目中使用 Axios,因此这里需要一个方法来获取 axios 实例 .method({ name: 'getAxios' }) // 声明四个请求方式对应的方法 const methods = ['get', 'post', 'put', 'delete'] methods.forEach(method => { IApi.method({ name: method, args: null, implement: function() { // 处理了 this 指向问题,放心用吧 return this.getAxios()[method].apply(this, arguments) .then(responseHandler) .catch(errorHandler) } }) })
const A = new Interface({ name: 'A', debug: true }).extends([B, C, D, E])
Die Methode deklariert alle von gehaltenen Methoden Die eingehende Schnittstelle (d. h. die durch extends
deklarierten Methoden) wird auf die Schnittstelle A kopiert, einschließlich der Standardimplementierung dieser Methodendeklarationen. Interface.method(config)
Achtung!
Im Allgemeinen wird dieselbe Methodensignatur nicht in mehreren Schnittstellen überschrieben, aber wenn Sie wirklich einen solchen Bedarf haben, können Sie Ihre eigenen Regeln festlegen, wie zum Beispiel: id
const B = new Interface(...) .method({ id: 'B00', name: 'getName', args = [...] }) .method({ id: 'B01', name: 'getName', args = [...] }) const C = new Interface(...) .method({ id: 'C00', name: 'getName', args = [...] })
// 注意!如果一个方法被重载,则不能在 class 中声明该方法。 class AImpl { ... } const AInstance = new AImpl(...) B.implement({ object: AInstance, id: 'B00', // 指定要实现的方法声明 name: 'getName' })
const IAuthenticationApi = new Interface({ name: 'IAuthentication', debug: true }) // 指明 IAuthenticationApi 继承自 IApi 接口 .extends(IApi) IAuthenticationApi // 重载方法 login // loin (username :string, password :string) .method({ id: 0, name: 'login', args: [ {name: 'username', type: 'string', support: val => typeof val === 'string'}, {name: 'password', type: 'string', support: val => typeof val === 'string'} ] }) // login() .method({ id: 1, name: 'login' })
// 编写一个实现类 class AuthenticationApi { constructor(axios) { this.axios = axios } // 直接实现 getName 方法 getName() { return "AuthenticationApi" } // 直接实现 getAxios 方法 getAxios() { return this.axios } } // 实现重载方法 IAuthenticationApi .implement({ // 指定挂载实现到 AuthenticationApi 上 object: AuthenticationApi, // 指定此实现是对应 id 为 0 的方法声明 id: 0, name: 'login', implement: function(username, password) { console.log('带参数的 login') // 还记得我们在 IApi 接口中定义了 get 方法(包括默认实现)吗? this.get('https://www.baidu.com') return Promise.resolve('hello') } }) .implement({ object: AuthenticationApi, id: 1, name: 'login', implement: function () { console.log('无参数的 login') }, }) IAuthenticationApi.ensureImplements(AuthenticationApi)
let authenticationService = new AuthenticationApi(axios) // 挂载代理函数到实例上,否则会提示 // Uncaught TypeError: authenticationService.login is not a function IAuthenticationApi.ensureImplements(authenticationService) authenticationService .login('sitdownload', '1498696873') // login(string, string) 会返回一个 Promise 还记得吗 :P .then(str => alert(`${str} world!`)) authenticationService.login()
). { debug: true }
// 注册方法 Interface 注册方法: IApi.getName() Interface 注册方法: IApi.getAxios() Interface 注册方法: IApi.get(any) Interface 注册方法: IApi.post(any) Interface 注册方法: IApi.put(any) Interface 注册方法: IApi.delete(any) Interface 注册方法: IAuthentication extends IApi.getName() Interface 注册方法: IAuthentication extends IApi.getAxios() Interface 注册方法: IAuthentication extends IApi.get(any) Interface 注册方法: IAuthentication extends IApi.post(any) Interface 注册方法: IAuthentication extends IApi.put(any) Interface 注册方法: IAuthentication extends IApi.delete(any) Interface 注册方法: [0]IAuthentication.login(username :string, password :string) Interface 注册方法: [1]IAuthentication.login() // 实现方法 Interface 实现方法: 保存 [0]IAuthentication.login(...) 实现: ƒ implement(username, password) Interface 实现方法: 保存 [1]IAuthentication.login(...) 实现: ƒ implement() // 匹配方法 Interface 方法匹配: 精准匹配 IAuthentication.login({ username: "sitdownload" } :string, { password: "1498696873" } :string). // 在控制台这行是可以打开实现的具体位置的 ƒ implement(username, password) // 方法输出 AuthenticationApi.js?7b55:25 带参数的 login // 匹配方法 Interface 方法匹配: 无法精准匹配 IAuthentication.get("https://www.baidu.com"),使用 any 实现匹配: ƒ implement() Interface 方法匹配: 精准匹配 IAuthentication.login(). ƒ implement() // 方法输出 AuthenticationApi.js?7b55:35 无参数的 login // AuthenticationApi.login(username, password) 中请求了 'https://www.baidu.com' Failed to load https://www.baidu.com/: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1' is therefore not allowed access. // IApi.get(any) 中将异常直接向下抛了 Uncaught (in promise) {type: "network", payload: Error: Network Error at createError (webpack-internal:///./node_modules/_axios@0.18.0@axios/lib/…}
keine Überprüfung der Eingabeparameter und keine Debugging-Ausgabe erfolgt. Interface
Ich glaube, dass Sie die Methode beherrschen, nachdem Sie den Fall in diesem Artikel gelesen haben. Weitere spannende Informationen finden Sie in anderen verwandten Artikeln auf der chinesischen PHP-Website!
Empfohlene Lektüre:
Analyse echter Front-End-Interviewfragen
Detaillierte Erläuterung der Schritte zur Kombination von React mit TypeScript und Mobx
Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung der Schritte zur Verwendung von Schnittstellen in JS. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!