在JS中有比typeof更好的方法来获取变量的类型吗?当你这样做时,它工作得很好:

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

但当你尝试的时候,它是无用的:

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

我知道instanceof,但这需要您事先知道类型。

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

有没有更好的办法?


当前回答

一行函数:

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

这将得到与jQuery.type()相同的结果

其他回答

我的2¢!实际上,我在这里提出这个问题的部分原因(尽管有很长的答案列表)是为了提供更多的一种类型解决方案,并在将来获得一些关于如何扩展它以包括更多真实类型的反馈。

With the following solution, as aforementioned, I combined a couple of solutions found here, as well as incorporate a fix for returning a value of jQuery on jQuery defined object if available. I also append the method to the native Object prototype. I know that is often taboo, as it could interfere with other such extensions, but I leave that to user beware. If you don't like this way of doing it, simply copy the base function anywhere you like and replace all variables of this with an argument parameter to pass in (such as arguments[0]).

;(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'

注意:有1个参数可传递。如果是true的bool类型,则返回值总是小写。

更多的例子:

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

如果你有任何可能有帮助的东西要添加,比如定义一个对象是什么时候用另一个库(Moo, Proto, Yui, Dojo等…)创建的,请随时评论或编辑这篇文章,让它更加准确和精确。或者转到我为它做的GitHub上,让我知道。你还可以在那里找到一个指向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();
}

在我的初步测试中,这工作得很好。第一种情况将打印用“new”创建的任何对象的名称,第二种情况将捕获其他所有对象。

我使用(8,-1)是因为我假设结果总是以[object]开始,以[object]结束,但我不确定在每种情况下都是这样。

我做了这个函数:

(您应该将其命名为更唯一的,这样它就不会与其他全局名称冲突。)

function type(theThing) {
    return Object.prototype.toString.call(theThing).match(/\s([\w]+)/)[1].toLowerCase()
}
type({})           //-> 'object'
type([])           //-> 'array'
type(function(){}) //-> 'function'
    
type(null)         //-> 'null'
type(undefined)    //-> 'undefined
type(true)         //-> 'boolean'
type('hello')      //-> 'string'
type(42)           //-> 'number'

type(Symbol())     //-> 'symbol'
type(/abc/)        //-> 'regexp'
type(new Set())    //-> 'set'
// etc ...

PS:上面的F.NiX做了更健壮的版本,它还告诉你从Class或构造函数中创建的自定义对象的名称。

我想这里最通用的解决方案是首先检查undefined和null,然后调用constructor.name.toLowerCase()。

const getType = v =>
  v === undefined
    ? 'undefined'
    : v === null
      ? 'null'
      : v.constructor.name.toLowerCase();




console.log(getType(undefined)); // 'undefined'
console.log(getType(null)); // 'null'
console.log(getType('')); // 'string'
console.log(getType([])); // 'array'
console.log(getType({})); // 'object'
console.log(getType(new Set())); // `set'
console.log(getType(Promise.resolve())); // `promise'
console.log(getType(new Map())); // `map'

安格斯·克罗尔最近写了一篇有趣的博文

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()
}