获取Javascript变量类型的更好方法?

获取Javascript变量类型的更好方法?,javascript,types,typeof,Javascript,Types,Typeof,有没有比typeof更好的方法来获取JS中变量的类型?当您执行以下操作时,它工作正常: > typeof 1 "number" > typeof "hello" "string" 但当你尝试时,它是无用的: > typeof [1,2] "object" >r = new RegExp(/./) /./ > typeof r "function" 我知道instanceof,但这需要您事先知道类型 > [1,2] instanceof Array true

有没有比
typeof
更好的方法来获取JS中变量的类型?当您执行以下操作时,它工作正常:

> 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

有更好的方法吗?

您可以尝试使用
构造函数.name

[].constructor.name
new RegExp().constructor.name
与JavaScript一样,最终总会有人指出这是邪恶的,所以这很好地涵盖了这一点

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

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

您可以对任何对象应用
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除外-当对从另一个窗口获取的变量调用此函数时,它只会吐出
[对象对象]

一个相当好的类型捕获函数用于:


这捕获了javascript提供的许多原语,但是您可以通过修改
类型
对象来添加更多的原语。请注意,Safari中HTMLElementCollection的
类型将报告
函数
,但类型(HTMLElementCollection)将返回
对象

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

他分析了各种方法的优缺点,然后定义了一个新方法“toType”-

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

功能类型(obj){
返回Object.prototype.toString.call(obj).replace(/^\[Object(+)\]$/,“$1”).toLowerCase()
}

这给出了与

相同的结果,我们还可以从ipr101

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

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

您可能会发现以下功能很有用:

function typeOf(obj) {
  return {}.toString.call(obj).split(' ')[1].slice(0, -1).toLowerCase();
}
或在ES7中(如果需要进一步改进,请发表意见)

结果:

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
感谢@johnres通知我:错误、承诺、发电机功能

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
开始,以
]
结束,但我不确定这在每个场景中都是正确的。

我的2!事实上,我在这里提出这个问题的部分原因,尽管答案列表很长,是为了提供更多的
多功能一体式解决方案,并在将来获得一些关于如何扩展它以包含更多
实型的反馈

对于下面的解决方案,如前所述,我结合了这里找到的两个解决方案,并合并了一个修复程序,用于在jQuery定义的对象上返回值(如果可用)。我还将该方法附加到本机对象原型中。我知道这通常是禁忌,因为它可能会干扰其他此类扩展,但我将此留给
用户注意
。如果您不喜欢这种方式,只需将基函数复制到您喜欢的任何位置,并用要传入的参数(如参数[0])替换
this
的所有变量即可

然后轻松使用,如下所示:

obj.realType()  //  would return 'Object'
obj.realType(true)  //  would return 'object'
注意:有一个参数可以通过。如果布尔值为
,则返回值将始终为小写

更多示例:

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

如果您有任何需要添加的内容,例如定义对象是何时使用另一个库(Moo、Proto、Yui、Dojo等)创建的,请随时对其进行评论或编辑,并使其更加准确。或者滚到我为它做的地方让我知道。您还可以在那里找到一个指向cdn min文件的快速链接。

我想这里最通用的解决方案是首先检查
未定义的
null
,然后只需调用
构造函数.name.toLowerCase()


typeof
条件用于检查变量类型,如果您要在if-else条件中检查变量类型 e、 g


此版本更为完整:

const typeOf = obj => {
  let type = ({}).toString.call(obj).match(/\s([a-zA-Z]+)/)[1]
  if (type === 'Object') {
    const results = (/^(function|class)\s+(\w+)/).exec(obj.constructor.toString())
    type = (results && results.length > 2) ? results[2] : ''
  }
  return type.toLowerCase()
}
现在不仅你可以得到这些结果:(正如这里已经回答的)

但您也可以从类或函数中获取您构造的每个实例或对象的类型:(这在其他答案之间无效,所有答案都返回object)


name
是ECMAScript的一个扩展,不会在所有浏览器中都起作用。由于确认javascript中所做的一切都是邪恶的,所以进行了投票。邪恶:如果你正在缩小你的代码,那么
构造函数。name
可能会变成类似于
n
的东西,而不是你期望的对象名。所以要注意这一点——特别是如果你只是在生产中缩小规模。
null
undefined
不幸的是没有构造函数。JavaScript本身是邪恶的。而且很傻。这个问题没有好答案的事实就是活生生的证明。@Xeon我认为对IE的仇恨有点过分了。IE9是一款比它的前辈好得多的浏览器。@Pessimopotamus但没有人会将浏览器更新为IE9使用IE。IE9是朝着正确方向迈出的一步,IE10看起来相当不错。顺便说一句,我提到的错误是IE9中的一个回归-他们在IE8中修复了它。这里有一个有趣的旁注-这可能会破坏“主机”对象传递给函数的地方。例如,Internet Explorer
ActiveXObject
实例。如果您创建了自己的对象类型(原型继承),如何让它返回比“object”更具体的值?这也是一个问题,但从未解决。如果您的类型命名包含:或u,则可以将此正则表达式扩展为
匹配(/\s([a-z,,:,a-z]+)/)
正则表达式还需要包含
Uint8Array
之类的数字。相反,请考虑更一般的<代码>匹配(/\s([^ \])+)/代码>,它应该处理任何事情。我建议使用<代码> \W Word运算符代替…FYI,<代码>类型n
obj.realType()  //  would return 'Object'
obj.realType(true)  //  would return 'object'
true.realType();                            //  "Boolean"
var a = 4; a.realType();                    //  "Number"
$('div:first').realType();                   // "jQuery"
document.createElement('div').realType()    //  "HTMLDivElement"
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'
if(typeof Varaible_Name "undefined")
{

}
const typeOf = obj => {
  let type = ({}).toString.call(obj).match(/\s([a-zA-Z]+)/)[1]
  if (type === 'Object') {
    const results = (/^(function|class)\s+(\w+)/).exec(obj.constructor.toString())
    type = (results && results.length > 2) ? results[2] : ''
  }
  return type.toLowerCase()
}
undefined or empty -> undefined
null -> null
NaN -> number
5 -> number
{} -> object
[] -> array
'' -> string
function () {} -> function
/a/ -> regexp
new Date() -> date
new Error -> error
Promise.resolve() -> promise
function *() {} -> generatorfunction
new WeakMap() -> weakmap
new Map() -> map
class C {
  constructor() {
    this.a = 1
  }
}

function F() {
  this.b = 'Foad'
}

typeOf(new C()) // -> c
typeOf(new F()) // -> f