深刻探究JavaScript對象系列(六)

一.類和類型

  在傳統的面向對象的編程語言中,有很好的方法可以判斷一個實例對象屬於哪一個類,可是在js中,並無完美方法來實現這個功能,可是仍是有幾種方法來彌補,下面介紹3種:程序員

  a.instanceof運算符和isPrototype()方法,編程

  instanceof操做符的左操做數是待檢測其類的對象,右操做數是定義類的構造函數,若是o繼承自c.prototype,則表達式 o instanceof c 返回true.,此外當o繼承自一個也繼承自c.prototype的對象時也會返回true;一樣的isPrototype()方法也能實現相似功能,即在多個執行上下文場景中沒法正常工做。數組

  可是着兩個都沒法經過對象來得到類名,此外在客戶端JavaScript中,出現多窗口和多框架子頁面中兼容性不佳框架

  b.constructor屬性編程語言

  這個屬性在上一篇中剛剛提到過,用這個屬性能夠得到類名,但在多個執行上下文中的場景中也沒法政策工做,並且並非全部的對象中都具備這個屬性。函數

  c。使用構造函數的函數名spa

  上述的兩類方法在用來檢測對象所屬類中都有「多個執行上下文場景中沒法正常工做」的問題,一種可能的解決方案是使用構造函數名稱字符串,可是這樣作在當構造函數沒有名稱的時候也沒法正常工做。prototype

二.鴨式辯型

  鴨式辯型這個思考問題的方式是由James Riley提出的,它的思想是:像鴨子同樣走路,游泳而且嘎嘎叫的鳥就是鴨子。code

  對於程序員來講:不要關注對象類型是什麼,而是關注對象能作什麼。拿上一篇中的例二來講,Range中的includes方法並無對實參進行類型檢測以確保它是數字類型,就直接拿來比較;此外在類數組對象中這點顯得尤其明顯,在不少場景蝦,咱們並不知道一個對象是否爲數組對象,能夠經過判斷該對象是否包含一個length的屬性,有就認爲它是數組對象,即這隻「鴨子」會游泳了,會不會走路和嘎嘎叫則不去判斷。對象

  鴨式辯型的實現方法讓人感受太「聽任自流」:僅僅是假設輸入的對象實現了必要的方法,沒有進一步執行檢查。若是輸入對象沒有遵循以前的「假設」,那麼當代碼試圖調用那些根本不存在的方法時就會報錯;另外一種實現方法是對輸入對象進行檢查,但不是檢查它們的類,而是用適合的名字來檢查它們所實現的方法,這樣能夠將非法輸入儘量的攔截在前,並給出有效提示,請看下面的例子:

 1 function quacks(o /*,...*/){
 2     for (var i = 1; i < arguments.length; i++) {
 3         var arg = arguments[i];
 4         switch(typeof arg){
 5             case "string" :       //直接用名字作檢查
 6                 if(typeof o[arg] !== "function") return false;
 7                 continue;
 8             case "function" :
 9                 arg = arg.prototype;
10                 continue;
11             case "object":
12                 for(var m in arg){
13                     if(typeof arg[m] !== "function") continue;
14                     if(typeof o[m] !== "function") return false;
15                 }
16                 continue;
17         }
18     }
19     return true;
20 }

  關於這個quacks函數有亮點須要注意:咱們只是經過給定的名稱來檢測對象是否知足要求,但沒法得知其細節,而這也正是鴨式辯型的本質所在;此外該函數該函數不能應用於內置類,由於內置類中的方法都是沒法經過for/in來遍歷的。

  到此爲止,算上以前5篇,再加上這一篇基本上以及把JavaScript中的面向對象的基礎介紹完了,接下來會介紹些JavaScript中關於面向對象編程的技術,固然仍是基於David Flanagan大神的那本《JavaScript權威指南》。

相關文章
相關標籤/搜索