是否有更好的方法来获取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
有更好的方法吗?
答案 0 :(得分:205)
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()
}
答案 1 :(得分:46)
您可以尝试使用constructor.name
。
[].constructor.name
new RegExp().constructor.name
与所有JavaScript一样,有人最终会指出这是某种邪恶,所以here is a link to an answer很好地涵盖了这一点。
另一种方法是使用Object.prototype.toString.call
Object.prototype.toString.call([])
Object.prototype.toString.call(/./)
答案 2 :(得分:38)
一个相当不错的类型捕获函数是YUI3使用的函数:
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
,但类型(HTMLElementCollection)将返回object
答案 3 :(得分:25)
您可能会发现以下功能有用:
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
typeOf(new WeakMap()) //weakmap
typeOf(new Map()) //map
感谢@johnrees通知我:错误,承诺,生成器功能
答案 4 :(得分:14)
我们也可以从 ipr101
改变一个小例子Object.prototype.toType = function() {
return ({}).toString.call(this).match(/\s([a-zA-Z]+)/)[1].toLowerCase()
}
并致电
"aaa".toType(); // 'string'
答案 5 :(得分:8)
一行函数:
function type(obj) {
return Object.prototype.toString.call(obj).replace(/^\[object (.+)\]$/,"$1").toLowerCase()
}
的结果相同
答案 6 :(得分:3)
您可以将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除外 - 当从另一个窗口获取的变量上调用它时,它只会吐出[object Object]
。
答案 7 :(得分:3)
我的2¢!真的,我把这个放在这里的部分原因,尽管有很长的答案清单,是为了提供更多 {{1 }} 输入解决方案并在将来获取一些反馈,了解如何扩展它以包含更多 all in one
。
通过以下解决方案,如上所述,我结合了这里找到的几个解决方案,并在real types
。如果您不喜欢这种方式,只需将基函数复制到您喜欢的任何位置,并用参数参数替换user beware
的所有变量以传入(例如arguments [0])。
this
然后简单地使用,就像这样:
;(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;
})();
注意:有1个参数可通过。如果是
obj.realType() // would return 'Object' obj.realType(true) // would return 'object'
的bool,则返回将始终为小写。
更多例子:
true
如果您要添加任何可能有用的内容,例如定义何时使用其他库(Moo,Proto,Yui,Dojo等等)创建对象,请随时评论或编辑此内容并继续使用更准确和准确。或者滚动到我为它制作的GitHub并告诉我。你还可以找到一个快速链接到那里的cdn min文件。
答案 8 :(得分:2)
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
开头,以]
结尾,但我不是确定在每种情况下都是如此。
答案 9 :(得分:0)
我想这里最通用的解决方案是先检查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'
答案 10 :(得分:0)
typeof
条件用于检查变量类型,如果您在if-else条件下检查变量类型
例如
if(typeof Varaible_Name "undefined")
{
}
答案 11 :(得分:0)
此版本是更完整的版本:
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
答案 12 :(得分:-1)
我做了这个功能:
(您应该将其命名为更独特的,以免与其他一些全局名称冲突。)
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(Symbol()) //-> 'symbol'
type(true) //-> 'boolean'
type('hello') //-> 'string'
type(42) //-> 'number'