JavaScript では、インターフェイスは一連の抽象メソッドとメソッド特性のコレクションの宣言であり、オブジェクトがどのメソッドを持つ必要があるかを記述する手段を提供します。インターフェイスはコードの再利用性を促進し、異なるクラス間の通信を安定させ、2 つのオブジェクトを継承する過程で発生する問題を軽減します。
このチュートリアルの動作環境: Windows7 システム、JavaScript バージョン 1.8.5、Dell G3 コンピューター。
インターフェースとは
インターフェースは、一連の抽象メソッドとメソッド特性のコレクションの宣言です。これらのメソッドはすべては、特定のクラスによって実装される必要があり、その後、サードパーティがこの抽象メソッドのセットを呼び出して、特定のクラスに特定のメソッドを実行させることができます。
インターフェイスは、オブジェクト指向 JavaScript プログラマのツールボックスの中で最も便利なツールの 1 つです。デザインパターンで提唱される再利用可能なオブジェクト指向設計の原則の一つに「実装プログラミングではなくインターフェースのためのプログラミング」、いわゆるインターフェース指向プログラミングがあり、この概念の重要性は明らかです。
しかし、問題は、JavaScript の世界には、インターフェイスを作成または実装するための組み込みメソッドがなく、オブジェクトが別のオブジェクトと同じものを実装しているかどうかを判断できる一連のメソッドも存在しないことです。オブジェクト間の関係を作成するため、これらを互換的に使用するのは困難ですが、幸いなことに、JavaScript には優れた柔軟性があるため、従来のオブジェクト指向インターフェイスをシミュレートし、これらの機能を追加することが簡単にできます。
インターフェイスは、オブジェクトが持つべきメソッドを指定する手段を提供します。これらのメソッドの意味を示すことはできますが、特定の実装は含まれません。このツールを使用すると、オブジェクトが提供するプロパティによってオブジェクトをグループ化できます。
たとえば、A と B、およびインターフェイス I の場合、A オブジェクトと B オブジェクトが大きく異なっていても、両方が I インターフェイスを実装している限り、A は A.I( B) 方法および B.I(A) と同様。
インターフェイスを使用して、さまざまなクラス間の共通性を高めることもできます。元々特定のクラスをパラメータとして必要とする関数を、特定のインターフェイスをパラメータとして必要とする関数に変更すると、そのインターフェイスを実装するすべてのオブジェクトをパラメータとして渡すことができます。相互に関連するオブジェクトをパラメータとして渡すことができ、オブジェクトも同様に扱うことができます。
インターフェイスの長所と短所
確立されたインターフェイスは自己記述的であり、コードの再利用性を促進できます。インターフェイスは、外部クラスに伝えるための一種の情報を提供できます。どのようなメソッドを実装する必要があるか。また、異なるクラス間の通信方法が安定し、2 つのオブジェクトを継承する過程で発生する問題が軽減されます。
これはデバッグにも役立ちます。JavaScript のような弱い型指定言語では、型の不一致を追跡するのが困難です。インターフェイスの使用時に問題が発生すると、より明確なエラー メッセージが表示されます。もちろん、インターフェイスにも欠点がないわけではありません。インターフェイスを多用すると、弱い型付け言語としての柔軟性がある程度低下します。一方、JavaScript にはインターフェイスのサポートが組み込まれておらず、従来のオブジェクトをシミュレートするだけです。これにより、本質的に柔軟性のある JavaScript の制御がより困難になります。
さらに、インターフェイスを実装するどの方法でも、追加のメソッド呼び出しオーバーヘッドが部分的に原因として、パフォーマンスに影響を与えます。インターフェイスを使用する場合の最大の問題は、他の厳密に型指定された言語とは異なり、JavaScript がインターフェイス規約に準拠していない場合、コンパイルに失敗することです。その柔軟性により、上記の問題を効果的に回避できます。共同開発環境の場合、そのインターフェイスは、エラーを引き起こさずに破損する可能性が非常に高く、制御できません。
オブジェクト指向言語では、インターフェイスの使用方法は一般的に似ています。インターフェイスに含まれる情報には、クラスが実装する必要があるメソッドと、これらのメソッドのシグネチャが記述されています。クラス定義では、これらのインターフェイスを実装することを明示的に記述する必要があります。そうしないと、クラスはコンパイルされません。
明らかに、JavaScript では同じことを行うことはできません。インターフェイスや実装キーワードが存在せず、インターフェイスが規則に従っているかどうか実行時にチェックされないためです。しかし、補助メソッドを使用してそれを模倣することはできます。および明示的なチェック、そのプロパティのほとんど。
JavaScript でインターフェイスを実装する方法
JavaScript でインターフェイスを実装するには 3 つの方法があります:
(1) コメントインターフェイスの説明
(2) 属性検出インターフェイス
##(3) アヒルの種類識別インターフェイス##1. コメント説明インターフェイス: 非推奨/** * interface Composite{ * function a(); * function b(); * } */ // CompositeImpl implements Composite var CompositeImpl = function(){ //业务逻辑 }; CompositeImpl.prototype.a = function(){ //业务逻辑 }; CompositeImpl.prototype.b = function(){ //业务逻辑 };
缺点:并未确保类真正实现了自称实现的接口。你只知道它是否说自己实现了接口。
var interfacesImpl = function(){ //在实现类内部用一个数组保存要实现的方法名 //通常这个属性名是团队中规定好的 //声明自己实现了这两个方法,但实际上并不一定 this.implementsInterfaces = ["Composite","FormItem"]; }; //专门为这个实现对象写一个检测函数,传入实例对象,用于检查实例对象是否实现了所有接口 function checkImplements(obj){ //调用检查方法 obj是否实现了两个接口,如果没有都实现则抛出异常 if(!isImplements(obj,"Composite","FormItem")){ throw new Error("接口没有全部实现!"); } //obj是要检查的对象 function isImplements(obj){ //传入的第0个参数是要检查的对象,所以从1开始检查 for(var i=1; i<arguments.length; i++){ //接收接口中每个接口的名字 var interfaceName = arguments[i]; //默认未实现该接口 var foundFlag = false; //循环查询传入实例对象的实现接口数组,检查是否全部实现 for(var j=0; j<obj.implementsInterfaces.length; j++){ //如果实现了这个接口,就修改标记并跳出 //debugger if(obj.implementsInterfaces[j] == interfaceName){ foundFlag = true; break; } } //如果遍历实现接口数组之后没找到,返回false if(!foundFlag){ return false; } } return true; } } //使用实例对象并检测 var o = new interfacesImpl(); checkImplements(o);
背后的观点:如果对象具有与接口定义的方法同名的所有方法,那么久可以认为它实现了这个接口。
/** * 接口类 * * @param {String} name 接口的名字 * @param {Array} methods 要实现方法名称的数组 */ var Interface = function (name, methods) { //判断参数个数 if(arguments.length !== 2){ throw new Error("接口构造器参数必须是两个!"); } this.name = name; this.methods = []; for(var i=0; i<methods.length; i++){ if(typeof methods[i] !== "string"){ throw new Error("接口实现的函数名称必须是字符串!"); } this.methods.push(methods[i]); } } //实例化接口对象---传入接口名和要实现的方法数组 var CompositeInterface = new Interface("CompositeInterface",["add","remove"]); var FormItemInterface = new Interface("FormItemInterface",["update","select"]); //实现接口的类 var CompositeImpl = function(){ } //实现接口的方法 CompositeImpl.prototype.add = function(obj){ //... } CompositeImpl.prototype.remove = function(obj){ //... } CompositeImpl.prototype.select = function(obj){ //... } //在这里少实现一个方法,下面检查是否全部实现了接口 // CompositeImpl.prototype.update = function(obj){ // //... // } //实例化 实现接口的对象 var c = new CompositeImpl(); //检验接口里的方法是否全部实现,如果不通过则抛出异常 Interface.ensureImplements = function(obj){ //如果接收到参数小于2,说明异常 if(arguments.length < 2){ throw new Error("接口检查方法的参数必须多余两个!"); } //接口实现检查 for(var i=0,len = arguments.length; i<len; i++){ //获取当前接口 var instanceInterface = arguments[i]; //判断接收到的是不是接口的对象,如果不是则抛出异常 if(instanceInterface.constructor !== Interface){ throw new Error("接口检测函数必须传入接口对象!"); } //检查实例化接口的对象是不是实现了接口里的所有方法 for(var j=0; j<instanceInterface.methods.length; j++){ //接收到的字符串方法 var methodName = instanceInterface.methods[j]; //如果obj里面没有methodsName这个方法,或者有这个属性但是不是函数,就抛出异常 if(!obj[methodName] || typeof obj[methodName] !== "function"){ throw new Error("接口方法" + methodName + "没有实现!"); } } } } //传入要检查的类,和要实现的所有接口对象 Interface.ensureImplements(c, CompositeInterface, FormItemInterface); c.add();
【相关推荐:javascript学习教程】
以上がJavaScriptのインターフェースとは何ですかの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。