今回は、JSでインターフェースを使用する手順について詳しく説明します。JSでインターフェースを使用する際の注意点について、実際のケースを見てみましょう。
この記事は、あまり複雑なものではありませんが、「
JavaScript」という本を読んだときのソースコードの考え方を書いておきます。
デザインパターン」の第 2 章では、多くのデザインパターンを使いやすくするために JavaScript でインターフェース (インターフェース) をシミュレートするという概念について説明しましたので、インターフェースのシミュレーションを作成してみてください。私はバックエンド Java 開発者なので、インターフェースのデフォルト実装、インターフェース継承、メソッドのオーバーロード、その他の機能をこのシミュレーション層に追加したいと考えていますが、これらの機能を追加した後はこれは避けられません。パフォーマンスは多少犠牲になりますが、私にとっては開発経験をいくらか向上させることができます (TypeScript は知っていますが、ホイールで試してみたいだけです :P)。 使い方本来の目的はApiの管理を容易にすることなので、Apiに関するデモを作成しましょう。
インターフェースを作成する
const config = { // 接口的名字 name: 'IApi', // 是否打开此接口的 debug 开关 // 开发时必须打开,否则不会启动 (方法声明、方法实现等)入参的类型检查。 // 打开这个的情况下,还会获得一些调试用的信息。 debug: true, } let IApi = new Interface(config)
メソッドを宣言する
宣言する最も簡単な方法:
IApi.method({name: 'getName'}) // 等价于 IApi.method({name: 'getName', args: undefined})
これは、IApi
インターフェースに getName
メソッドが含まれていることを宣言します。パラメータがあり、デフォルトの実装はありません。そのためには、 IApi
の後続のサブインターフェースまたは実装クラスがこのメソッドを実装する必要があります。実装しない場合は、例外がスローされます。
メソッドのパラメータリストを指定したい場合:
IApi.method({ name: 'getName', args: null })
IApi
接口含有一个 getName
方法,它没有任何参数,也没有默认实现,这就要求在后面任何 IApi
的子接口或实现类必须实现该方法,否则会抛出一个异常。
如果想指定方法的参数列表:
// 声明一个空参方法 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'} ] })
注意!
args
为 null
时表示该方法可以接受任意数量的任意参数,如果重载了一个方法(详细的请参阅后面关于重载的说明):
IApi.method({ name: 'getName', // 默认实现,不能为箭头函数! implement: function() { return "IApi" } })
注意!
在参数描述中,type
属性只是一个字符串值,它并不真的代表参数的实际类型。它跟 name
属性一样只是提供用于调试的信息,因此你可以填入任何你认为合适的、足以标记该参数一些信息的字符串值。
真正决定方法是否接受该参数的是 support
属性,当它返回 true
时会检查下一个参数直到所有参数检查完毕或某个位置的参数不被接受。
如果需要,可以在 support
中对实际入参进行特殊处理,比如转换对象、特定属性检查等等。
如果想为方法提供默认实现:
// 声明两个方法,它们都没有参数,也不需要重载因此这样就可以了 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) } }) })
回到我们的 demo,综合运用一下:
const A = new Interface({ name: 'A', debug: true }).extends([B, C, D, E])
继承接口
假定我们要创建接口 A,要继承 B、C、D、E 等接口,使用如下语句:
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 = [...] })
extends
方法会将传入的接口所持有的所有方法声明(即通过 Interface.method(config)
所声明的那些方法 )拷贝至接口 A,包括那些方法声明的默认实现。
注意!
一般来说,不会在多个接口中重载同一个方法签名,但如果真的有这样的需求,可以自行设置 id
的规则,比如:
// 注意!如果一个方法被重载,则不能在 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' })
再次回到我们的 demo,综合运用一下:
// 编写一个实现类 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()
使用接口实现类
// 注册方法 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/…}
关于日志
首先确保在创建接口时打开了 debug 开关({ debug: true }
)。
上面的 demo 运行正常的话你将会得到下面的日志:
rrreee后续
如果要发版了,确认所有的接口方法都正确实现后,就可以把 debug 关掉,这样就不会有 Interface
注意!
args
が null
の場合、メソッドがオーバーロードされている場合、メソッドは任意の数のパラメーターを受け入れることができることを意味します (詳細については、オーバーロードの説明を参照してください)後ほど) :🎜rreee🎜🎜注意! 🎜🎜🎜パラメータの説明では、type
属性 🎜 は単なる 文字列です🎜 値は、実際にはパラメータの実際の型を表しません。 🎜 name
属性と同様、デバッグ用の情報のみを提供するため、パラメータに何らかの情報をマークするのに十分で適切だと思われる文字列値を入力できます。 🎜🎜メソッドがこのパラメータを受け入れるかどうかを実際に決定するのは、support
属性です。true
が返された場合、すべてのパラメータがチェックされるまで、次のパラメータがチェックされます。特定の位置では受け入れられません。 🎜🎜必要に応じて、support
の実際の入力パラメータに対して、オブジェクトの変換、特定の属性のチェックなどの特別な処理を実行できます。 🎜🎜メソッドのデフォルト実装を提供する場合: 🎜rrreee
🎜デモに戻って包括的に使用します: 🎜rrreee🎜インターフェイスを継承します🎜🎜インターフェイス A を作成するとします。 B と C 、D、E およびその他のインターフェイスを継承するには、次のステートメントを使用します: 🎜rrreee🎜
extends
メソッドは、受信インターフェイスによって保持されるすべてのメソッドを宣言します (つまり、Interface.method を通じて) (config)
code>) は、これらのメソッド宣言のデフォルト実装を含めて、インターフェイス A にコピーされます。 🎜🎜🎜注意! 🎜🎜🎜一般的に、同じメソッド シグネチャは複数のインターフェイスでオーバーライドされませんが、本当にそのような必要がある場合は、次のように id
のルールを自分で設定できます。 🎜rrreee🎜Thenこのメソッドを実装するときは、どのステートメントを実装するかを指定します:🎜rrreee🎜もう一度デモに戻って、包括的に使用してください:🎜rrreee🎜インターフェイスを実装します🎜rrreee🎜インターフェイスを使用してクラスを実装します🎜rrreee🎜概要log🎜🎜まず、インターフェイス (
{ debug: true }
) の作成時にデバッグ スイッチがオンになっていることを確認します。 🎜🎜上記のデモが正常に実行されると、次のログが取得されます: 🎜rrreee🎜フォローアップ🎜🎜 バージョンをリリースしたい場合は、すべてのインターフェースメソッドが正しく実装されていることを確認した後、デバッグをオフにすることができます。 Interface
内では、一部の入力パラメータのチェックやデバッグ出力は行われません。 🎜この記事の事例を読んだ後は、その方法を習得したと思います。さらに興味深い情報については、php 中国語 Web サイトの他の関連記事に注目してください。
推奨書籍:
以上がJSでインターフェイスを使用する手順の詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

はじめに私はあなたがそれを奇妙に思うかもしれないことを知っています、JavaScript、C、およびブラウザは正確に何をしなければなりませんか?彼らは無関係であるように見えますが、実際、彼らは現代のウェブ開発において非常に重要な役割を果たしています。今日は、これら3つの間の密接なつながりについて説明します。この記事を通して、JavaScriptがブラウザでどのように実行されるか、ブラウザエンジンでのCの役割、およびそれらが協力してWebページのレンダリングと相互作用を駆動する方法を学びます。私たちは皆、JavaScriptとブラウザの関係を知っています。 JavaScriptは、フロントエンド開発のコア言語です。ブラウザで直接実行され、Webページが鮮明で興味深いものになります。なぜJavascrを疑問に思ったことがありますか

node.jsは、主にストリームのおかげで、効率的なI/Oで優れています。 ストリームはデータを段階的に処理し、メモリの過負荷を回避します。大きなファイル、ネットワークタスク、リアルタイムアプリケーションの場合。ストリームとTypeScriptのタイプの安全性を組み合わせることで、パワーが作成されます

PythonとJavaScriptのパフォーマンスと効率の違いは、主に以下に反映されています。1)解釈された言語として、Pythonはゆっくりと実行されますが、開発効率が高く、迅速なプロトタイプ開発に適しています。 2)JavaScriptはブラウザ内の単一のスレッドに限定されていますが、マルチスレッドおよび非同期I/Oを使用してnode.jsのパフォーマンスを改善でき、両方とも実際のプロジェクトで利点があります。

JavaScriptは1995年に発信され、Brandon Ikeによって作成され、言語をCに実現しました。 2。JavaScriptのメモリ管理とパフォーマンスの最適化は、C言語に依存しています。 3. C言語のクロスプラットフォーム機能は、さまざまなオペレーティングシステムでJavaScriptを効率的に実行するのに役立ちます。

JavaScriptはブラウザとnode.js環境で実行され、JavaScriptエンジンに依存してコードを解析および実行します。 1)解析段階で抽象的構文ツリー(AST)を生成します。 2)ASTをコンパイル段階のバイトコードまたはマシンコードに変換します。 3)実行段階でコンパイルされたコードを実行します。

PythonとJavaScriptの将来の傾向には、1。Pythonが科学コンピューティングの分野での位置を統合し、AI、2。JavaScriptはWebテクノロジーの開発を促進します。どちらもそれぞれのフィールドでアプリケーションシナリオを拡大し続け、パフォーマンスをより多くのブレークスルーを行います。

開発環境におけるPythonとJavaScriptの両方の選択が重要です。 1)Pythonの開発環境には、Pycharm、Jupyternotebook、Anacondaが含まれます。これらは、データサイエンスと迅速なプロトタイピングに適しています。 2)JavaScriptの開発環境には、フロントエンドおよびバックエンド開発に適したnode.js、vscode、およびwebpackが含まれます。プロジェクトのニーズに応じて適切なツールを選択すると、開発効率とプロジェクトの成功率が向上する可能性があります。

はい、JavaScriptのエンジンコアはCで記述されています。1)C言語は、JavaScriptエンジンの開発に適した効率的なパフォーマンスと基礎となる制御を提供します。 2)V8エンジンを例にとると、そのコアはCで記述され、Cの効率とオブジェクト指向の特性を組み合わせて書かれています。3)JavaScriptエンジンの作業原理には、解析、コンパイル、実行が含まれ、C言語はこれらのプロセスで重要な役割を果たします。


ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

SublimeText3 英語版
推奨: Win バージョン、コードプロンプトをサポート!

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

SecLists
SecLists は、セキュリティ テスターの究極の相棒です。これは、セキュリティ評価中に頻繁に使用されるさまざまな種類のリストを 1 か所にまとめたものです。 SecLists は、セキュリティ テスターが必要とする可能性のあるすべてのリストを便利に提供することで、セキュリティ テストをより効率的かつ生産的にするのに役立ちます。リストの種類には、ユーザー名、パスワード、URL、ファジング ペイロード、機密データ パターン、Web シェルなどが含まれます。テスターはこのリポジトリを新しいテスト マシンにプルするだけで、必要なあらゆる種類のリストにアクセスできるようになります。

SAP NetWeaver Server Adapter for Eclipse
Eclipse を SAP NetWeaver アプリケーション サーバーと統合します。

ホットトピック









