2010-05-05 40 views
2

很明顯,instanceoftypeof都無法正確識別每個javascript對象的類型。我已經拿出這個功能,我正在尋找一些反饋:這是識別JavaScript對象類型的好方法嗎?

function getType() { 

     var input = arguments[0] ; 

     var types = ["String","Array","Object","Function","HTML"] ; //!! of the top of my head 

     for(var n=0; n < types.length; n++) { 

      if(input.constructor.toString().indexOf(types[n]) != -1) { 
       document.write(types[n]) ; 
      } 

     } 

    } 

感謝您的閱讀!

回答

3

對於某些情況,依賴於instanceof運算符是not good enough

一個已知的問題是它不能在跨幀環境中工作。

typeof操作者不那麼有用,並有一些實現錯誤,例如像在Chrome或Firefox 2.x的,其中RegExp對象被檢測爲"function",因爲他們作可調用(例如/foo/(str);)。

constructor財產可以篡改,你應該永遠倍受信賴它。

最後,Function.prototype.toString方法是實現相關,這意味着實施可能不包括即使在函數的字符串表示的函數名稱...

一些days ago我是建立一個簡單的但功能強大的類型檢測函數,它使用typeof作爲原始值,並依賴於[[Class]]內部屬性的對象。

所有對象都具有這個屬性,實現在內部使用,以檢測對象的,它是完全不變,並且只能通過Object.prototype.toString方法訪問:

用法:

//... 
if (typeString(obj) == 'array') { 
    //.. 
} 

實現:

function typeString(o) { 
    if (typeof o != 'object') 
    return typeof o; 

    if (o === null) 
     return "null"; 
    //object, array, function, date, regexp, string, number, boolean, error 
    var internalClass = Object.prototype.toString.call(o) 
               .match(/\[object\s(\w+)\]/)[1]; 
    return internalClass.toLowerCase(); 
} 

該函數的second variant更爲嚴格,因爲它僅返回ECMAScript規範中描述的內置對象類型。

可能輸出值:

原語:

  • "number"
  • "string"
  • "boolean"
  • "undefined"
  • "null"
  • "object"

內置對象類型(通過[[Class]]

  • "function"
  • "array"
  • "date"
  • "regexp"
  • "error"
+1

你贏得你的74K的聲譽,CMS。 – 2010-05-05 18:37:08

+0

好東西。謝謝!你能否詳細說明爲什麼使用'constructor'屬性不是一個好主意,因爲它可以被「篡改」? – FK82 2010-05-05 19:10:46

+0

@Diobeus,thanks !, @ FK82我的意思是'constructor'屬性是可寫的,而且格式錯誤的對象會給你提供錯誤的結果。 ('var re =/foo /; re.constructor = null;'),你也可以在自定義類型上實現繼承時設置錯誤的'constructor' [甚至沒有注意到](http://joost.zeekat.nl/constructors -considered-mildly-confusing.html)... – CMS 2010-05-05 20:07:11

1

類似的問題出現了幾天前。我打開了jQuery 1.4.2,看看它在那裏已經完成了。下面是我的結果到目前爲止,你能爲他們的休息我敢肯定,運行檢查:

(function() { 

    // Define the base sys namespace 
    this.sys = function() { }; 

    var toString = Object.prototype.toString; 

    //from jQuery 1.4.2  
    sys.isFunction = function(obj) { 
     return toString.call(obj) === "[object Function]"; 
    } 

    //from jQuery 1.4.2 
    sys.isArray = function(obj) { 
     return toString.call(obj) === "[object Array]"; 
    } 
} 

用法:

if (sys.isArray(myObject)) doStuff(); 
+0

看起來類似於CMS的技術。 – 2010-05-05 18:33:10

+0

是的。他們似乎都在使用相同的機制。不管怎麼說,還是要謝謝你。 – FK82 2010-05-05 19:14:42

相關問題