在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

有没有更好的办法?


当前回答

您可以尝试使用constructor.name。

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

就像所有JavaScript一样,最终总会有人指出这在某种程度上是邪恶的,所以这里有一个链接,可以很好地回答这个问题。

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

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

其他回答

您可以尝试使用constructor.name。

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

就像所有JavaScript一样,最终总会有人指出这在某种程度上是邪恶的,所以这里有一个链接,可以很好地回答这个问题。

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

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

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

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

Typeof条件用于检查变量类型,如果你在if-else条件下检查变量类型 如。

if(typeof Varaible_Name "undefined")
{

}

你可能会发现以下函数很有用:

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

或者在ES7中(如果有进一步改进请评论)

const { toString } = Object.prototype;

function typeOf(obj) {
  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
typeOf(new WeakMap()) //weakmap
typeOf(new Map()) //map
typeOf(async function() {}) //asyncfunction

感谢@johnrees通知我:错误,承诺,生成器函数

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]结束,但我不确定在每种情况下都是这样。