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