JavaScript中是否有类似Java的class.getName()?
当前回答
Lodash有很多isMethods,所以如果你在使用Lodash,可能像这样的mixin会很有用:
// Mixin for identifying a Javascript Object
_.mixin({
'identify' : function(object) {
var output;
var isMethods = ['isArguments', 'isArray', 'isArguments', 'isBoolean', 'isDate', 'isArguments',
'isElement', 'isError', 'isFunction', 'isNaN', 'isNull', 'isNumber',
'isPlainObject', 'isRegExp', 'isString', 'isTypedArray', 'isUndefined', 'isEmpty', 'isObject']
this.each(isMethods, function (method) {
if (this[method](object)) {
output = method;
return false;
}
}.bind(this));
return output;
}
});
它为lodash添加了一个名为“identify”的方法,其工作原理如下:
console.log(_.identify('hello friend')); // isString
砰砰作响: http://plnkr.co/edit/Zdr0KDtQt76Ul3KTEDSN
其他回答
下面是我提出的解决instanceof缺点的解决方案。它可以从跨窗口和跨框架检查对象的类型,并且在基本类型方面没有问题。
function getType(o) {
return Object.prototype.toString.call(o).match(/^\[object\s(.*)\]$/)[1];
}
function isInstance(obj, type) {
var ret = false,
isTypeAString = getType(type) == "String",
functionConstructor, i, l, typeArray, context;
if (!isTypeAString && getType(type) != "Function") {
throw new TypeError("type argument must be a string or function");
}
if (obj !== undefined && obj !== null && obj.constructor) {
//get the Function constructor
functionConstructor = obj.constructor;
while (functionConstructor != functionConstructor.constructor) {
functionConstructor = functionConstructor.constructor;
}
//get the object's window
context = functionConstructor == Function ? self : functionConstructor("return window")();
//get the constructor for the type
if (isTypeAString) {
//type is a string so we'll build the context (window.Array or window.some.Type)
for (typeArray = type.split("."), i = 0, l = typeArray.length; i < l && context; i++) {
context = context[typeArray[i]];
}
} else {
//type is a function so execute the function passing in the object's window
//the return should be a constructor
context = type(context);
}
//check if the object is an instance of the constructor
if (context) {
ret = obj instanceof context;
if (!ret && (type == "Number" || type == "String" || type == "Boolean")) {
ret = obj.constructor == context
}
}
}
return ret;
}
isInstance需要两个参数:一个对象和一个类型。它工作的真正技巧是检查对象是否来自同一个窗口,如果不是,则获取对象的窗口。
例子:
isInstance([], "Array"); //true
isInstance("some string", "String"); //true
isInstance(new Object(), "Object"); //true
function Animal() {}
function Dog() {}
Dog.prototype = new Animal();
isInstance(new Dog(), "Dog"); //true
isInstance(new Dog(), "Animal"); //true
isInstance(new Dog(), "Object"); //true
isInstance(new Animal(), "Dog"); //false
type参数也可以是返回构造函数的回调函数。回调函数将接收一个参数,该参数是所提供对象的窗口。
例子:
//"Arguments" type check
var args = (function() {
return arguments;
}());
isInstance(args, function(w) {
return w.Function("return arguments.constructor")();
}); //true
//"NodeList" type check
var nl = document.getElementsByTagName("*");
isInstance(nl, function(w) {
return w.document.getElementsByTagName("bs").constructor;
}); //true
需要记住的一件事是IE < 9没有提供所有对象的构造函数,因此上面的NodeList测试将返回false,而且isInstance(alert,“Function”)也将返回false。
使用Object.prototype.toString
正如这篇文章所详述的那样,你可以使用Object.prototype.toString——toString的低级通用实现——来获取所有内置类型的类型
Object.prototype.toString.call('abc') // [object String]
Object.prototype.toString.call(/abc/) // [object RegExp]
Object.prototype.toString.call([1,2,3]) // [object Array]
可以编写一个简短的辅助函数,例如
function type(obj){
return Object.prototype.toString.call(obj]).match(/\s\w+/)[0].trim()
}
return [object String] as String
return [object Number] as Number
return [object Object] as Object
return [object Undefined] as Undefined
return [object Function] as Function
你能得到的最接近的是typeof,但它只返回任何自定义类型的“object”。关于这些,请参阅Jason Bunting。
编辑,Jason因为某种原因删除了他的帖子,所以只使用Object的构造函数属性。
你应该像这样使用somevar.constructor.name:
const getVariableType = a => a.constructor.name. tolowercase (); const d = new Date(); const res = getVariableType(d);/ /“日期” Const num = 5; const res2 = getVariableType(num);/ /“数量” Const fn = () => {}; const res3 = getVariableType(fn);/ /函数的 console.log (res1);/ /“日期” console.log(它);/ /“数量” console.log (res3);/ /函数的
更新
准确地说,我认为OP要求一个检索特定对象的构造函数名称的函数。在Javascript中,object没有类型,但它本身就是一种类型。但是,不同的对象可以有不同的构造函数。
Object.prototype.getConstructorName = function () {
var str = (this.prototype ? this.prototype.constructor : this.constructor).toString();
var cname = str.match(/function\s(\w*)/)[1];
var aliases = ["", "anonymous", "Anonymous"];
return aliases.indexOf(cname) > -1 ? "Function" : cname;
}
new Array().getConstructorName(); // returns "Array"
(function () {})().getConstructorName(); // returns "Function"
注意:下面的示例已弃用。
一篇由Christian Sciberras链接的博客文章提供了一个如何做到这一点的好例子。也就是说,通过扩展Object原型:
if (!Object.prototype.getClassName) {
Object.prototype.getClassName = function () {
return Object.prototype.toString.call(this).match(/^\[object\s(.*)\]$/)[1];
}
}
var test = [1,2,3,4,5];
alert(test.getClassName()); // returns Array