获取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 ExplorerActiveXObject
实例。如果您创建了自己的对象类型(原型继承),如何让它返回比“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