Maison >interface Web >js tutoriel >Explication détaillée des étapes d'utilisation des interfaces en JS
Cette fois je vais vous donner une explication détaillée des étapes d'utilisation des interfaces en JS Quelles sont les précautions pour utiliser les interfaces en JS Voici des cas pratiques, jetons un coup d'œil.
Voici le README de js-interface Bien que ce ne soit pas une chose très compliquée, si quelqu'un peut le lire, j'écrirai les idées du code source ORZ
JavaScript Design Patterns", chapitre 2. mentionné que dans Le concept de simulation d'interfaces (interface) en JavaScript facilite l'utilisation de nombreux modèles de conception, j'ai donc essayé de simuler une interface. Puisque je suis un développeur back-end Java, j'espère ajouter Implémentation par défaut de l'interface, Héritage de l'interface, à cette couche de simulation Méthode la surcharge et d'autres fonctionnalités, bien que l'ajout de ces éléments sacrifiera inévitablement les performances, pour moi, cela peut améliorer une certaine expérience de développement (je connais TypeScript, je voulais juste me procurer une roue et l'essayer : P).
Utiliser Puisque l'intention initiale est de faciliter la gestion d'Api, alors faites une démo sur Api. Créer une interfaceconst config = { // 接口的名字 name: 'IApi', // 是否打开此接口的 debug 开关 // 开发时必须打开,否则不会启动 (方法声明、方法实现等)入参的类型检查。 // 打开这个的情况下,还会获得一些调试用的信息。 debug: true, } let IApi = new Interface(config)Déclarer les méthodesLa manière la plus simple de déclarer :
IApi.method({name: 'getName'}) // 等价于 IApi.method({name: 'getName', args: undefined})De cette façon, l'
interface contient Une méthode IApi
n'a aucun paramètre ni aucune implémentation par défaut, ce qui nécessite que toute sous-interface getName
ou classe d'implémentation ultérieure implémente cette méthode, sinon une exception sera levée. IApi
IApi.method({ name: 'getName', args: null })
Attention !
Lorsqu'il est args
, cela signifie que la méthode peut accepter n'importe quel nombre de paramètres si une méthode est surchargée (pour plus de détails, veuillez vous référer à la description de la surcharge plus tard) : 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'} ] })
Attention !
Dans la description du paramètre, l'attribut type
est juste une valeur chaîne, qui ne représente pas vraiment le type réel du paramètre. Comme l'attribut , il fournit uniquement des informations pour le débogage, vous pouvez donc remplir n'importe quelle valeur de chaîne que vous jugez suffisamment appropriée pour marquer le paramètre avec des informations. name
. Lorsqu'il renvoie support
, le paramètre suivant sera vérifié jusqu'à ce que tous les paramètres soient vérifiés ou qu'un paramètre à une certaine position ne soit pas accepté. . true
, comme la conversion d'objets, la vérification d'attributs spécifiques, etc. 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) } }) })Hériter de l'interface Supposons que nous voulions créer l'interface A et hériter des interfaces B, C, D, E, etc., utilisez l'instruction suivante :
const A = new Interface({ name: 'A', debug: true }).extends([B, C, D, E])
Le La méthode passera dans l'interface détenue par Toutes les déclarations de méthode (c'est-à-dire celles déclarées via extends
) sont copiées dans l'interface A, y compris l'implémentation par défaut de ces déclarations de méthode. Interface.method(config)
Attention !
De manière générale, la même signature de méthode ne sera pas remplacée dans plusieurs interfaces, mais si vous en avez vraiment besoin, vous pouvez définir vos propres règles, telles que : 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 = [...] })Spécifiez ensuite quelle instruction implémenter lors de l'implémentation de la méthode :
// 注意!如果一个方法被重载,则不能在 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' })Implémentez la interface
// 编写一个实现类 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)Utilisez l'interface pour implémenter la classe
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()À propos du journal Assurez-vous d'abord que le commutateur de débogage (
) est activé lorsque création de l'interface. { 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/…}SuiviSi vous souhaitez publier la version, confirmez que toutes les interfaces les méthodes sont implémentées correctement. Après cela, vous pouvez désactiver le débogage, de sorte qu'il n'y ait pas de vérification des paramètres d'entrée ni de sortie de débogage à l'intérieur de
. Interface
Je pense que vous maîtrisez la méthode après avoir lu le cas dans cet article. Pour des informations plus intéressantes, veuillez prêter attention aux autres articles connexes sur le site Web chinois de php !
Lecture recommandée :
Analyse de véritables questions d'entretien front-end
Explication détaillée des étapes de combinaison de React avec TypeScript et Mobx
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!