您好,登錄后才能下訂單哦!
今天小編給大家分享一下javascript中的接口是什么意思的相關知識點,內容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。
在javascript中,接口是一系列抽象方法的聲明,是一些方法特征的集合,它提供了一種用以說明一個對象應該具有哪些方法的手段。接口能夠促進代碼的重用性,還有助于穩定不同類之間的通信方式,減少了繼承兩個對象的過程中出現的問題。
本教程操作環境:windows7系統、javascript1.8.5版、Dell G3電腦。
什么是接口
接口是一系列抽象方法的聲明,是一些方法特征的集合,這些方法都應該是抽象的,需要由具體的類去實現,然后第三方就可以通過這組抽象方法調用,讓具體的類執行具體的方法。
接口是面向對象JavaScript程序員的工具箱中最有用的工具之一。在設計模式中提出的可重用的面向對象設計的原則之一就是“針對接口編程而不是實現編程”,即我們所說的面向接口編程,這個概念的重要性可見一斑。
但問題在于,在JavaScript的世界中,沒有內置的創建或實現接口的方法,也沒有可以判斷一個對象是否實現了與另一個對象相同的一套方法,這使得對象之間很難互換使用,好在JavaScript擁有出色的靈活性,這使得模擬傳統面向對象的接口,添加這些特性并非難事。
接口提供了一種用以說明一個對象應該具有哪些方法的手段,盡管它可以表明這些方法的含義,但是卻不包含具體實現。有了這個工具,就能按對象提供的特性對它們進行分組。
例如,假如A和B以及接口I,即便A對象和B對象有極大的差異,只要他們都實現了I接口,那么在A.I(B)方法中就可以互換使用A和B,如B.I(A)。
還可以使用接口開發不同的類的共同性。如果把原本要求以一個特定的類為參數的函數改為要求以一個特定的接口為參數的函數,那么所有實現了該接口的對象都可以作為參數傳遞給它,這樣一來,彼此不相關的對象也可以被相同地對待。
接口的利與弊
既定的接口具有自我描述性,并能夠促進代碼的重用性,接口可以提供一種信息,告訴外部一個類需要實現哪些方法。還有助于穩定不同類之間的通信方式,減少了繼承兩個對象的過程中出現的問題。
這對于調試也是有幫助的,在JavaScript這種弱類型語言中,類型不匹配很難追蹤,使用接口時,如果出現了問題,會有更明確的錯誤提示信息。當然接口并非完全沒有缺點,如果大量使用接口會一定程度上弱化其作為弱類型語言的靈活性,另一方面,JavaScript并沒有對接口的內置的支持,只是對傳統的面向對象的接口進行模擬,這會使本身較為靈活的JavaScript變得更加難以駕馭。
此外,任何實現接口的方式都會對性能造成影響,某種程度上歸咎于額外的方法調用開銷。接口使用的最大的問題在于,JavaScript不像是其他的強類型語言,如果不遵守接口的約定,就會編譯失敗,其靈活性可以有效地避開上述問題,如果是在協同開發的環境下,其接口很有可能被破壞而不會產生任何錯誤,也就是不可控性。
在面向對象的語言中,使用接口的方式大體相似。接口中包含的信息說明了類需要實現的方法以及這些方法的簽名。類的定義必須明確地聲明它們實現了這些接口,否則是不會編譯通過的。
顯然在JavaScript中我們不能如法炮制,因為不存在interface和implement關鍵字,也不會在運行時對接口是否遵循約定進行檢查,但是我們可以通過輔助方法和顯式地檢查模仿出其大部分特性。
javascript中怎么實現接口
JavaScript中有三種方式實現接口:
(1)注釋描述接口
(2)屬性檢測接口
(3)鴨式辨型接口
優點:易于實現,不需要額外的類或函數。
缺點:純文檔約束,程序不能檢查實現接口的對象是否實現了所有接口方法
/** * 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中的接口是什么意思”這篇文章的所有內容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。