更好的方式来获得一个Javascriptvariables的types?

有没有更好的方式来获取JS中的variablestypes比typeof ? 它可以正常工作,当你这样做:

 > typeof 1 "number" > typeof "hello" "string" 

但是当你尝试的时候没用

 > typeof [1,2] "object" >r = new RegExp(/./) /./ > typeof r "function" 

我知道instanceof ,但是这需要你事先知道types。

 > [1,2] instanceof Array true > r instanceof RegExp true 

有没有更好的办法?

Angus Croll最近写了一篇有趣的博客文章 –

http://javascriptweblog.wordpress.com/2011/08/08/fixing-the-javascript-typeof-operator/

他经历了各种方法的利弊,然后定义了一个新的方法“toType” –

 var toType = function(obj) { return ({}).toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase() } 

你可以尝试使用constructor.name

 [].constructor.name new RegExp().constructor.name 

就像所有JavaScript一样,最终总会有人指出这是某种邪恶的东西,所以这里有一个涵盖这个很好的答案的链接 。

另一种方法是使用Object.prototype.toString.call

 Object.prototype.toString.call([]) Object.prototype.toString.call(/./) 

YUI3使用的合适的types捕获函数是:

 var TYPES = { 'undefined' : 'undefined', 'number' : 'number', 'boolean' : 'boolean', 'string' : 'string', '[object Function]': 'function', '[object RegExp]' : 'regexp', '[object Array]' : 'array', '[object Date]' : 'date', '[object Error]' : 'error' }, TOSTRING = Object.prototype.toString; function type(o) { return TYPES[typeof o] || TYPES[TOSTRING.call(o)] || (o ? 'object' : 'null'); }; 

这捕获了由JavaScript提供的许多基元,但是您可以随时通过修改TYPES对象来添加更多。 请注意,Safari中的typeof HTMLElementCollection将报告function ,但types(HTMLElementCollection)将返回object

您可能会发现以下function有用:

 function typeOf(obj) { return {}.toString.call(obj).split(' ')[1].slice(0, -1).toLowerCase(); } 

或者在ES7(如果进一步改进,评论)

 function typeOf(obj) { const { toString } = Object.prototype; const stringified = obj::toString(); const type = stringified.split(' ')[1].slice(0, -1); return type.toLowerCase(); } 

结果:

 typeOf(); //undefined typeOf(null); //null typeOf(NaN); //number typeOf(5); //number typeOf({}); //object typeOf([]); //array typeOf(''); //string typeOf(function () {}); //function typeOf(/a/) //regexp typeOf(new Date()) //date typeOf(new Error) //error typeOf(Promise.resolve()) //promise typeOf(function *() {}) //generatorfunction 

感谢@johnrees通知我:错误,承诺,发电机function

我们也可以从ipr101改变一个小例子

 Object.prototype.toType = function() { return ({}).toString.call(this).match(/\s([a-zA-Z]+)/)[1].toLowerCase() } 

并称之为

 "aaa".toType(); // 'string' 

一行function:

 function type(obj) { return Object.prototype.toString.call(obj).replace(/^\[object (.+)\]$/,"$1").toLowerCase() } 

这给出了与jQuery.type()相同的结果

您可以将Object.prototype.toString应用于任何对象:

 var toString = Object.prototype.toString; console.log(toString.call([])); //-> [object Array] console.log(toString.call(/reg/g)); //-> [object RegExp] console.log(toString.call({})); //-> [object Object] 

这适用于所有的浏览器,IE除外 – 在从另一个窗口获得的variables上调用它时,它只会吐出[object Object]

我的2¢! 真的,我在这里抛出这个问题的部分原因,尽pipe答案很长,但是all in onetypes的解决scheme中提供了更多的all in one并且在将来如何扩展它以包含更多的real types

通过以下解决scheme,如前所述,我将这里find的几个解决scheme进行了组合,并在jQuery定义的对象( 如果可用)上join了一个返回jQuery值的修复程序 。 我也将该方法附加到本机对象原型。 我知道这往往是禁忌,因为它可能会干扰其他这样的扩展,但我留给user beware 。 如果你不喜欢这样做的话,只要简单地复制你喜欢的任何地方的基本函数,并用参数传入的参数(比如arguments [0])replace掉所有的variables。

 ;(function() { // Object.realType function realType(toLower) { var r = typeof this; try { if (window.hasOwnProperty('jQuery') && this.constructor && this.constructor == jQuery) r = 'jQuery'; else r = this.constructor && this.constructor.name ? this.constructor.name : Object.prototype.toString.call(this).slice(8, -1); } catch(e) { if (this['toString']) r = this.toString().slice(8, -1); } return !toLower ? r : r.toLowerCase(); } Object['defineProperty'] && !Object.prototype.hasOwnProperty('realType') ? Object.defineProperty(Object.prototype, 'realType', { value: realType }) : Object.prototype['realType'] = realType; })(); 

然后简单地使用,就像这样:

 obj.realType() // would return 'Object' obj.realType(true) // would return 'object' 

注意:有一个参数可以通过。 如果是true ,那么返回将总是小写

更多示例:

 true.realType(); // "Boolean" var a = 4; a.realType(); // "Number" $('div:first').realType(); // "jQuery" document.createElement('div').realType() // "HTMLDivElement" 

如果你有什么需要补充的,比如定义一个对象是用另外一个库创build的(Moo,Proto,Yui,Dojo等等),请随意评论或编辑这个对象,并保持它的更多准确和精确。 或滚到我为它做的GitHub ,让我知道。 您还可以在那里find一个cdn min文件的快速链接。

 function getType(obj) { if(obj && obj.constructor && obj.constructor.name) { return obj.constructor.name; } return Object.prototype.toString.call(obj).slice(8, -1).toLowerCase(); } 

在我的初步testing中,这个工作非常好。 第一种情况将打印用“新”创build的任何对象的名称,第二种情况应该抓住一切。

我正在使用(8, -1)因为我假定结果始终以[object和end结束]开头,但我不确定在每种情况下都是如此。