2011-10-25 208 views
95

typeof運算符並不能真正幫助我們找到對象的實際類型。檢查JS對象類型的最準確的方法是什麼?

我已經看到了下面的代碼:

Object.prototype.toString.apply(t) 

問:

它是檢查對象的類型的準確的方法?

+2

看一看這篇文章:http://javascriptweblog.wordpress.com/2011/08/08/fixing-the-javascript-typeof-operator/ –

+4

看看這個帖子:HTTP: //stackoverflow.com/questions/332422/how-do-i-get-the-name-of-an-objects-type-in​​-javascript – isJustMe

+0

http://tobyho.com/2011/01/28/checking- types-in-javascript/ – airportyh

回答

129

JavaScript的規範給出恰好一個適當的方法來確定一個對象的類:

Object.prototype.toString.call(t); 

http://bonsaiden.github.com/JavaScript-Garden/#types

+3

如果你正在尋找一個特定的類型,你可能會想要做一些事情:Object.prototype.toString.call(new FormData())===「[object FormData]」'這將是真實的。你也可以使用'slice(8,-1)'返回'FormData'而不是'[object FormData]' –

+3

使用'Object.prototype'和'{}'有什麼不同? – GetFree

+3

也許這已經改變了多年,但'Object.prototype.toString.call(new MyCustomObject())'返回'[object Object]'而新MyCustomObject()instanceOf MyCustomObject返回true'這是我想要的(Chrome 54.0.2840.99米) – Maslow

9
var o = ... 
var proto = Object.getPrototypeOf(o); 
proto === SomeThing; 

保留對期望該對象的原型的句柄,然後與其進行比較。

例如

var o = "someString"; 
var proto = Object.getPrototypeOf(o); 
proto === String.prototype; // true 
+0

這是如何更好/不同於說'instanceof String; // TRUE'? –

+0

@jamietre因爲'「foo」instanceof String'中斷 – Raynos

+0

OK,所以「typeof(o)==='object'&& instanceof SomeObject」。測試字符串很容易。只是看起來像額外的工作,沒有解決必須事先知道你正在測試的基本問題。 –

52

Object.prototype.toString是一個很好的方法,但是它的性能是最差的。

http://jsperf.com/check-js-type

check js type performance

使用typeof解決一些基本問題(字符串,數字,布爾...),並使用Object.prototype.toString來解決複雜的東西(如數組,日期,正則表達式)。

,這是我的解決方案:

var type = (function(global) { 
    var cache = {}; 
    return function(obj) { 
     var key; 
     return obj === null ? 'null' // null 
      : obj === global ? 'global' // window in browser or global in nodejs 
      : (key = typeof obj) !== 'object' ? key // basic: string, boolean, number, undefined, function 
      : obj.nodeType ? 'object' // DOM element 
      : cache[key = ({}).toString.call(obj)] // cached. date, regexp, error, object, array, math 
      || (cache[key] = key.slice(8, -1).toLowerCase()); // get XXXX from [object XXXX], and cache it 
    }; 
}(this)); 

用作:

type(function(){}); // -> "function" 
type([1, 2, 3]); // -> "array" 
type(new Date()); // -> "date" 
type({}); // -> "object" 
+0

對jsPerf的測試不太準確。那些測試是不相同的(測試相同的東西)。 例如,typeof []返回「object」,typeof {}也返回「object」,即使一個是對象Array而另一個是對象Object。該測試還有許多其他問題... 在查看jsPerf時,請注意測試將蘋果與蘋果進行比較。 – kmatheny

+0

你的'type'函數很好,但是看看它和其他一些'type'函數相比如何。 [http://jsperf.com/code-type-test-a-test](http://jsperf.com/code-type-test-a-test) – Progo

+13

這些性能指標應該用一些常識來鍛鍊。當然,prototype.toString比其他的要慢一個數量級,但是在每個調用平均花費幾百納秒*的大事件中。除非在頻繁執行的關鍵路徑中使用此調用,否則這可能是無害的。我寧願直接轉發代碼,而不是比完成一微秒更快的代碼。 – David

7

接受的答案是正確的,但我喜歡來定義我建立大多數項目這個小工具。

var types = { 
    'get': function(prop) { 
     return Object.prototype.toString.call(prop); 
    }, 
    'object': '[object Object]', 
    'array': '[object Array]', 
    'string': '[object String]', 
    'boolean': '[object Boolean]', 
    'number': '[object Number]' 
} 

像這樣來使用:

if(types.get(prop) == types.number) { 

} 

如果您使用的角度,你甚至可以有它乾淨注入:

angular.constant('types', types); 
0

我放在一起靈感來自一個小類型檢查工具以上正確答案:

thetypeof = function(name) { 
     let obj = {}; 
     obj.object = 'object Object' 
     obj.array = 'object Array' 
     obj.string = 'object String' 
     obj.boolean = 'object Boolean' 
     obj.number = 'object Number' 
     obj.type = Object.prototype.toString.call(name).slice(1, -1) 
     obj.name = Object.prototype.toString.call(name).slice(8, -1) 
     obj.is = (ofType) => { 
      ofType = ofType.toLowerCase(); 
      return (obj.type === obj[ofType])? true: false 
     } 
     obj.isnt = (ofType) => { 
      ofType = ofType.toLowerCase(); 
      return (obj.type !== obj[ofType])? true: false 
     } 
     obj.error = (ofType) => { 
      throw new TypeError(`The type of ${name} is ${obj.name}: ` 
      +`it should be of type ${ofType}`) 
     } 
     return obj; 
    }; 

例如:

if (thetypeof(prop).isnt('String')) thetypeof(prop).error('String') 
if (thetypeof(prop).is('Number')) // do something 
相關問題