获取对象类型的名称


1193

是否有一个JavaScript的等效的Javaclass.getName()


这个问题假设我们知道Java的class.getName()做什么。由于我不知道,这些答案是否对我有帮助。
user34660 '18

2
@ user34660我认为我们可以放心地假设它所做的是获取对象类型的名称。
堆栈下溢

1
@StackUnderflow:除了,实际上不是。它得到一个对象的名称,这是一样的对象的类型
约尔格W¯¯米塔格

1
@JörgWMittag当然可以。看到您安全地假设事物时会发生什么?
Stack Underflow

Answers:


1540

是否有与Java等效的JavaScript class.getName()

没有

ES2015更新的名称class Foo {}Foo.namething不论类别如何,的类别名称thing均为thing.constructor.name。ES2015环境中的内置构造函数具有正确的name属性;例如(2).constructor.name"Number"


但是,这里有各种各样的骇客,它们都以一种或另一种方式下降:

这是一种可以满足您需要的技巧-请注意,它会修改Object的原型,而人们对此并不满意(通常是出于充分的理由)

Object.prototype.getName = function() { 
   var funcNameRegex = /function (.{1,})\(/;
   var results = (funcNameRegex).exec((this).constructor.toString());
   return (results && results.length > 1) ? results[1] : "";
};

现在,所有对象都将具有函数,该函数getName()将以字符串形式返回构造函数的名称。我已经在FF3和中对此进行了测试IE7,我不能说其他实现。

如果您不想这样做,这里是讨论在JavaScript中确定类型的各种方法...


我最近将其更新为更加详尽,尽管并非如此。欢迎更正...

使用constructor属性...

每个属性object都有其值constructor,但是取决于该值的object构造方式以及您要使用该值做什么,它可能有用也可能没有用。

一般来说,您可以使用constructor属性来测试对象的类型,如下所示:

var myArray = [1,2,3];
(myArray.constructor == Array); // true

因此,这足以满足大多数需求。那个...

注意事项

将无法正常工作在所有在许多情况下,

这种模式虽然很复杂,但却很常见:

function Thingy() {
}
Thingy.prototype = {
    method1: function() {
    },
    method2: function() {
    }
};

Objects通过构造的new Thingy将具有constructor指向而Object不是的属性Thingy。因此,我们一开始就陷入困境;您根本无法信任constructor您无法控制的代码库。

多重继承

一个不那么明显的例子是使用多重继承:

function a() { this.foo = 1;}
function b() { this.bar = 2; }
b.prototype = new a(); // b inherits from a

事情现在不起作用,您可能希望它们能够:

var f = new b(); // instantiate a new object with the b constructor
(f.constructor == b); // false
(f.constructor == a); // true

因此,如果object您的测试的object设置不同,则可能会得到意外的结果prototype。在此讨论范围之外,还有其他解决方法。

constructor物业还有其他用途,其中一些很有趣,而其他则不是很多。目前我们不会深入研究这些用途,因为它与本次讨论无关。

无法跨框架和跨窗口工作

使用.constructor进行类型检查时要检查从不同的未来对象的类型将打破window对象,说的iframe或弹出式窗口。这是因为constructor在每个“窗口” 中每种核心类型都有不同的版本,即

iframe.contentWindow.Array === Array // false

使用instanceof运算符...

instanceof运营商正在测试的一个干净的方式object式为好,但有自己潜在的问题,就像constructor财产。

var myArray = [1,2,3];
(myArray instanceof Array); // true
(myArray instanceof Object); // true

但是instanceof对于文字值无效(因为文字不是Objects

3 instanceof Number // false
'abc' instanceof String // false
true instanceof Boolean // false

该文本需要被包裹在一个Object为了instanceof工作,例如

new Number(3) instanceof Number // true

.constructor检查对于文字是有效的,因为.方法调用隐式地将文字包装在它们各自的对象类型中

3..constructor === Number // true
'abc'.constructor === String // true
true.constructor === Boolean // true

为什么两个点为3?因为Javascript将第一个点解释为小数点;)

无法跨框架和跨窗口工作

instanceof出于与constructor属性检查相同的原因,也无法在不同的窗口中工作。


使用name属性的constructor属性...

不工作在所有在许多情况下,

同样,见上文;constructor完全,完全错误和无用是很常见的。

在<IE9中不起作用

使用myObjectInstance.constructor.name将为您提供一个包含所constructor使用函数名称的字符串,但是要遵守constructor前面提到的有关属性的警告。

对于IE9及更高版本,您可以通过猴子补丁获得支持

if (Function.prototype.name === undefined && Object.defineProperty !== undefined) {
    Object.defineProperty(Function.prototype, 'name', {
        get: function() {
            var funcNameRegex = /function\s+([^\s(]+)\s*\(/;
            var results = (funcNameRegex).exec((this).toString());
            return (results && results.length > 1) ? results[1] : "";
        },
        set: function(value) {}
    });
}

有关文章的更新版本。此功能是在文章发布后3个月添加的,这是本文作者Matthew Scharley推荐使用的版本。此更改是受到注释的启发,这些注释指出了先前代码中的潜在陷阱

if (Function.prototype.name === undefined && Object.defineProperty !== undefined) {
    Object.defineProperty(Function.prototype, 'name', {
        get: function() {
            var funcNameRegex = /function\s([^(]{1,})\(/;
            var results = (funcNameRegex).exec((this).toString());
            return (results && results.length > 1) ? results[1].trim() : "";
        },
        set: function(value) {}
    });
}

使用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).slice(8, -1);
}

删除残留物并获取类型名称

type('abc') // String

但是,它将Object为所有用户定义的类型返回。


给所有人的警告...

所有这些都面临一个潜在的问题,那就是有关对象的构造方法。以下是构建对象的各种方法以及不同类型检查方法将返回的值:

// using a named function:
function Foo() { this.a = 1; }
var obj = new Foo();
(obj instanceof Object);          // true
(obj instanceof Foo);             // true
(obj.constructor == Foo);         // true
(obj.constructor.name == "Foo");  // true

// let's add some prototypical inheritance
function Bar() { this.b = 2; }
Foo.prototype = new Bar();
obj = new Foo();
(obj instanceof Object);          // true
(obj instanceof Foo);             // true
(obj.constructor == Foo);         // false
(obj.constructor.name == "Foo");  // false


// using an anonymous function:
obj = new (function() { this.a = 1; })();
(obj instanceof Object);              // true
(obj.constructor == obj.constructor); // true
(obj.constructor.name == "");         // true


// using an anonymous function assigned to a variable
var Foo = function() { this.a = 1; };
obj = new Foo();
(obj instanceof Object);      // true
(obj instanceof Foo);         // true
(obj.constructor == Foo);     // true
(obj.constructor.name == ""); // true


// using object literal syntax
obj = { foo : 1 };
(obj instanceof Object);            // true
(obj.constructor == Object);        // true
(obj.constructor.name == "Object"); // true

虽然这组示例中没有所有排列,但希望有足够的信息可以让您了解根据您的需求,事情可能变得多么混乱。不要假设任何事情,如果您不完全了解所要追求的目标,则可能会由于缺乏精妙之处而最终导致代码意外中断。

注意:

typeof运算符的讨论似乎是一个明显的遗漏,但object由于它非常简单,因此在帮助确定an 是否为给定类型方面确实没有用。了解在哪里typeof有用很重要,但是我目前不认为这与本次讨论非常相关。但是我的思想是开放的。:)


58
好吧,我想我也应该如此-Stack Overflow的要点有点像Wiki,我认为这更符合这一意图。无论如何,我只是想变得更彻底。
詹森·邦廷

在下面重新回答一个问题---您对Object原型的扩展在IE8中不起作用-有人知道在IE8中将起作用吗?
亚当

5
如果您像这样执行此功能,它将起作用a(){this.a = 1;} function b(){this.b = 2; } b.prototype = new a(); // b继承自b.prototype.constructor = b; //正确的原型继承方式var f = new b(); //使用b构造函数创建新对象(f.constructor == b); // TRUE(f.constructor == a); //假
鲍里斯·哈曼诺夫

9
现在,这就是大多数答案应该在StackOverflow上的方式。(不要将答案的长度作为定义参数,而是全面性)
kumarharsh 2012年

44
请务必注意,如果使用uglify之类的工具或Rails资产管道缩小了Javascript ,则检查对象constructor方法(使用.toString().name)的任何技术均将失效。缩小名称重命名了构造函数,因此您最终会得到不正确的类名,例如n。如果在这种情况下,您可能只想在对象上手动定义一个className属性,而改用它即可。
·马丁·丹佩西

126

杰森邦廷(Jason Bunting)的答案给了我足够的线索来找到我需要的东西:

<<Object instance>>.constructor.name

因此,例如,在下面的代码中:

function MyObject() {}
var myInstance = new MyObject();

myInstance.constructor.name会回来的"MyObject"


22
为了完整起见,值得一提的是,仅当您使用命名函数作为构造函数而不是分配给变量的匿名函数时,使用constructor.name才有效。
马修·克鲁姆利

20
为了完整起见,值得一提的是它在IE浏览器中不起作用---它们不支持函数的“ name”属性。
尤金·拉祖金

2
@Eugene-我忘了...我想我花了太多时间在浏览器之外做JavaScript。
马修·克鲁姆利

2
function getType(o) { return o && o.constructor && o.constructor.name }
justin.m.chase

这是如此全面。
ibic

26

我使用的一些小技巧:

function Square(){
    this.className = "Square";
    this.corners = 4;
}

var MySquare = new Square();
console.log(MySquare.className); // "Square"

11
我不是特别喜欢这个。这是一种肮脏的把戏。另一方面,如果您没有太多的构造函数,则可能工作正常。
pimvdb 2011年

13
@pimvdb:我认为这比修改对象的原型干净,这是公认的答案。
Daniel Szabo

4
@DanielSzabo如果某个属性在原型的所有实例之间应该具有相同的值,我绝对更喜欢将其放在原型上-将其放在每个实例上是超级冗余的,并且原型本身缺少元数据。也就是说,ES6中采用了最明智的解决方案:如果有class Square,名称是Square.name/ MySquare.constructor.name而不是Square.prototype.name; 通过name使用构造函数,它不会污染原型或任何实例,但可以从任何一个访问。
安迪

17

更新资料

确切地说,我认为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"

 


注意:以下示例已弃用。

一个博客帖子的链接基督教Sciberras包含有关如何做一个很好的例子。即,通过扩展对象原型:

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

2
很好,但是我们要再次命名:JS没有类。
mikemaccana 2012年

@nailer-我建议使用更新的功能,仅出于历史原因保留较旧的功能。
索尔

这是可行的,但应注意的是,可以通过创建一个将对象作为第一个参数并在函数内部使用“ this”而不是“ this”的函数来完成而无需修改Object.prototype。
马特·布朗

2
@Matt-好的。只是拥有对象方法更简洁:test.getClassName()vs getClassName.apply(test)
Saul 2012年

12

使用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

6
您不需要使用正则表达式来解析对象名称。只需使用.slice()Object.prototype.toString.call(obj).slice( 8, -1 );
bobobobo

9

这是我想出的解决方案,它解决了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。


8

我实际上正在寻找类似的东西,并遇到了这个问题。这是我获取类型的方法:jsfiddle

var TypeOf = function ( thing ) {

    var typeOfThing = typeof thing;

    if ( 'object' === typeOfThing ) {

        typeOfThing = Object.prototype.toString.call( thing );

        if ( '[object Object]' === typeOfThing ) {

            if ( thing.constructor.name ) {
                return thing.constructor.name;
            } 

            else if ( '[' === thing.constructor.toString().charAt(0) ) {
                typeOfThing = typeOfThing.substring( 8,typeOfThing.length - 1 );
            } 

            else {

                typeOfThing = thing.constructor.toString().match( /function\s*(\w+)/ );

                if ( typeOfThing ) { 
                    return typeOfThing[1];
                } 

                else {
                    return 'Function';
                }
            }
        } 

        else {
            typeOfThing = typeOfThing.substring( 8,typeOfThing.length - 1 );
        }
    }

    return typeOfThing.charAt(0).toUpperCase() + typeOfThing.slice(1);
}

7

您应该somevar.constructor.name像这样使用:

    
    const getVariableType = a => a.constructor.name.toLowerCase();

    const d = new Date();
    const res1 = getVariableType(d); // 'date'
    const num = 5;
    const res2 = getVariableType(num); // 'number'
    const fn = () => {};
    const res3 = getVariableType(fn); // 'function'

    console.log(res1); // 'date'
    console.log(res2); // 'number'
    console.log(res3); // 'function'


6

constructor.name在可以的情况下使用,而在我不能的情况下使用正则表达式。

Function.prototype.getName = function(){
  if (typeof this.name != 'undefined')
    return this.name;
  else
    return /function (.+)\(/.exec(this.toString())[1];
};

6

Agave.JSkind()函数将返回:

  • 继承树中最接近的原型
  • 对于总是原始类型(例如“ null”和“ undefined”)的原始名称。

它适用于所有JS对象和基元,而不管它们是如何创建的,也没有任何意外。例子:

号码

kind(37) === 'Number'
kind(3.14) === 'Number'
kind(Math.LN2) === 'Number'
kind(Infinity) === 'Number'
kind(Number(1)) === 'Number'
kind(new Number(1)) === 'Number'

N

kind(NaN) === 'NaN'

弦乐

kind('') === 'String'
kind('bla') === 'String'
kind(String("abc")) === 'String'
kind(new String("abc")) === 'String'

布尔值

kind(true) === 'Boolean'
kind(false) === 'Boolean'
kind(new Boolean(true)) === 'Boolean'

数组

kind([1, 2, 4]) === 'Array'
kind(new Array(1, 2, 3)) === 'Array'

对象

kind({a:1}) === 'Object'
kind(new Object()) === 'Object'

日期

kind(new Date()) === 'Date'

功能

kind(function(){}) === 'Function'
kind(new Function("console.log(arguments)")) === 'Function'
kind(Math.sin) === 'Function'

未定义

kind(undefined) === 'undefined'

空值

kind(null) === 'null'

5

您可以使用instanceof运算符查看对象是否是另一个对象的实例,但是由于没有类,因此无法获得类名。


尽管JavaScript确实没有使用类作为语言构造,但是通用约定仍然是将对象的类型称为类。。–
Saul

2
@greg当然可以,但是instanceof只检查一个对象是否继承自另一个对象。例如,简单[]继承自Array,但是Array也继承自Object。由于大多数对象都具有多个继承级别,因此找到最接近的原型是一种更好的技术。看到我的答案。
mikemaccana 2015年

4

这是基于接受的答案的实现

/**
 * Returns the name of an object's type.
 *
 * If the input is undefined, returns "Undefined".
 * If the input is null, returns "Null".
 * If the input is a boolean, returns "Boolean".
 * If the input is a number, returns "Number".
 * If the input is a string, returns "String".
 * If the input is a named function or a class constructor, returns "Function".
 * If the input is an anonymous function, returns "AnonymousFunction".
 * If the input is an arrow function, returns "ArrowFunction".
 * If the input is a class instance, returns "Object".
 *
 * @param {Object} object an object
 * @return {String} the name of the object's class
 * @see <a href="https://stackoverflow.com/a/332429/14731">https://stackoverflow.com/a/332429/14731</a>
 * @see getFunctionName
 * @see getObjectClass 
 */
function getTypeName(object)
{
  const objectToString = Object.prototype.toString.call(object).slice(8, -1);
  if (objectToString === "Function")
  {
    const instanceToString = object.toString();
    if (instanceToString.indexOf(" => ") != -1)
      return "ArrowFunction";
    const getFunctionName = /^function ([^(]+)\(/;
    const match = instanceToString.match(getFunctionName);
    if (match === null)
      return "AnonymousFunction";
    return "Function";
  }
  // Built-in types (e.g. String) or class instances
  return objectToString;
};

/**
 * Returns the name of a function.
 *
 * If the input is an anonymous function, returns "".
 * If the input is an arrow function, returns "=>".
 *
 * @param {Function} fn a function
 * @return {String} the name of the function
 * @throws {TypeError} if {@code fn} is not a function
 * @see getTypeName
 */
function getFunctionName(fn)
{
  try
  {
    const instanceToString = fn.toString();
    if (instanceToString.indexOf(" => ") != -1)
      return "=>";
    const getFunctionName = /^function ([^(]+)\(/;
    const match = instanceToString.match(getFunctionName);
    if (match === null)
    {
      const objectToString = Object.prototype.toString.call(fn).slice(8, -1);
      if (objectToString === "Function")
        return "";
      throw TypeError("object must be a Function.\n" +
        "Actual: " + getTypeName(fn));
    }
    return match[1];
  }
  catch (e)
  {
    throw TypeError("object must be a Function.\n" +
      "Actual: " + getTypeName(fn));
  }
};

/**
 * @param {Object} object an object
 * @return {String} the name of the object's class
 * @throws {TypeError} if {@code object} is not an Object
 * @see getTypeName
 */
function getObjectClass(object)
{
  const getFunctionName = /^function ([^(]+)\(/;
  const result = object.constructor.toString().match(getFunctionName)[1];
  if (result === "Function")
  {
    throw TypeError("object must be an Object.\n" +
      "Actual: " + getTypeName(object));
  }
  return result;
};


function UserFunction()
{
}

function UserClass()
{
}

let anonymousFunction = function()
{
};

let arrowFunction = i => i + 1;

console.log("getTypeName(undefined): " + getTypeName(undefined));
console.log("getTypeName(null): " + getTypeName(null));
console.log("getTypeName(true): " + getTypeName(true));
console.log("getTypeName(5): " + getTypeName(5));
console.log("getTypeName(\"text\"): " + getTypeName("text"));
console.log("getTypeName(userFunction): " + getTypeName(UserFunction));
console.log("getFunctionName(userFunction): " + getFunctionName(UserFunction));
console.log("getTypeName(anonymousFunction): " + getTypeName(anonymousFunction));
console.log("getFunctionName(anonymousFunction): " + getFunctionName(anonymousFunction));
console.log("getTypeName(arrowFunction): " + getTypeName(arrowFunction));
console.log("getFunctionName(arrowFunction): " + getFunctionName(arrowFunction));
//console.log("getFunctionName(userClass): " + getFunctionName(new UserClass()));
console.log("getTypeName(userClass): " + getTypeName(new UserClass()));
console.log("getObjectClass(userClass): " + getObjectClass(new UserClass()));
//console.log("getObjectClass(userFunction): " + getObjectClass(UserFunction));
//console.log("getObjectClass(userFunction): " + getObjectClass(anonymousFunction));
//console.log("getObjectClass(arrowFunction): " + getObjectClass(arrowFunction));
console.log("getTypeName(nativeObject): " + getTypeName(navigator.mediaDevices.getUserMedia));
console.log("getFunctionName(nativeObject): " + getFunctionName(navigator.mediaDevices.getUserMedia));

我们只有在别无选择时才使用构造函数属性。


3

您可以使用“ instanceof”运算符来确定对象是否是某个类的实例。如果您不知道对象类型的名称,则可以使用其构造函数属性。对象的构造函数属性是对用于初始化它们的函数的引用。例:

function Circle (x,y,radius) {
    this._x = x;
    this._y = y;
    this._radius = raduius;
}
var c1 = new Circle(10,20,5);

现在,c1.constructor是对该Circle()函数的引用。您也可以使用typeof运算符,但是typeof运算符显示的信息有限。一种解决方案是使用toString()Object全局对象的方法。例如,如果您有一个对象,例如myObject,则可以使用toString()全局Object 的方法来确定myObject类的类型。用这个:

Object.prototype.toString.apply(myObject);

3

说你有 var obj;

如果只需要obj类型的名称,例如“ Object”,“ Array”或“ String”,则可以使用以下方法:

Object.prototype.toString.call(obj).split(' ')[1].replace(']', '');

2

您可以获得的最接近的是typeof,但是对于任何类型的自定义类型,它仅返回“对象”。对于这些,请参阅Jason Bunting

编辑,Jason由于某种原因删除了他的帖子,因此只需使用Object的constructor属性即可。


是的,很抱歉-我删除了它,因为我认为instanceof()是做事的更好方法,但我只是取消删除它,以便可以将其用作参考。
詹森·邦廷

2
不够完美的答案仍然有用,即使只是对其他人稍后提出该问题,因为它们也有类似的问题。因此,您确实不应该删除它们。保存删除错误答案。
sblundy

2
是的,我知道-您正在宣讲合唱团,我已经对其他人说了同样的话。生活那些我们知道是真实的事情通常比看起来困难。:)
杰森邦廷

0

如果有人在寻找可以与jQuery配合使用的解决方案,请参阅以下经过调整的Wiki代码(原始版本破坏了jQuery)。

Object.defineProperty(Object.prototype, "getClassName", {
    value: function() {
        var funcNameRegex = /function (.{1,})\(/;
        var results = (funcNameRegex).exec((this).constructor.toString());
        return (results && results.length > 1) ? results[1] : "";
    }
});

是的,jQuery无法执行“ hasOwnProperty”检查,因此枚举getName和失败。
nicodemus13 2015年

0

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


0

好的,伙计们,多年来,我一直在为此逐步建立一种全面的方法,哈哈!诀窍是:

  1. 有创建类的机制。
  2. 有一种机制可以检查由本机构造函数创建/生成的所有用户创建的类,原语和值。
  3. 具有将用户创建的类扩展为新类的机制,以便上述功能贯穿您的代码/应用程序/库/等。

有关示例(或查看我如何处理该问题),请查看以下github上的代码:https : //github.com/elycruz/sjljs/blob/master/src/sjl/sjl.js并搜索:

classOf =,, classOfIs =和或 defineSubClass =(不带反引号(`))。

如您所见,我有一些机制可以强制classOf始终为我提供类/构造函数的类型名称,无论它是原始类型,用户定义的类,使用本机构造函数创建的值,Null,NaN等。对于每个单个javascript值,我将从classOf函数中获取它的唯一类型名称。另外,除了能够传入sjl.classOfIs值的类型名称之外,我还可以传入实际的构造函数以检查值的类型!因此,例如:

```//请原谅长名称空间!我不知道影响,直到使用了一段时间(他们都吮吸哈哈)

var SomeCustomClass = sjl.package.stdlib.Extendable.extend({
    constructor: function SomeCustomClass () {},
    // ...
}),

HelloIterator = sjl.ns.stdlib.Iterator.extend( 
    function HelloIterator () {}, 
    { /* ... methods here ... */ },
    { /* ... static props/methods here ... */ }
),

helloIt = new HelloIterator();

sjl.classOfIs(new SomeCustomClass(), SomeCustomClass) === true; // `true`
sjl.classOfIs(helloIt, HelloIterator) === true; // `true`

var someString = 'helloworld';

sjl.classOfIs(someString, String) === true; // `true`

sjl.classOfIs(99, Number) === true; // true

sjl.classOf(NaN) === 'NaN'; // true

sjl.classOf(new Map()) === 'Map';
sjl.classOf(new Set()) === 'Set';
sjl.classOfIs([1, 2, 4], Array) === true; // `true`

// etc..

// Also optionally the type you want to check against could be the type's name
sjl.classOfIs(['a', 'b', 'c'], 'Array') === true; // `true`!
sjl.classOfIs(helloIt, 'HelloIterator') === true; // `true`!

```

如果您有兴趣阅读有关我如何使用上述设置的更多信息,请查看存储库:https : //github.com/elycruz/sjljs

另外还包含有关该主题的内容的书:-Stoyan Stefanov撰写的“ JavaScript模式”。-《 Javascript-权威指南》。大卫·弗拉纳根(David Flanagan)。-和许多其他..(在le le Web上搜索)。

您也可以快速测试我谈论这里的特点: - http://sjljs.elycruz.com/0.5.18/tests/for-browser/(也是在URL中的0.5.18路径具有从GitHub源在那儿减去node_modules等。

编码愉快!


0

很简单!

  • 我最喜欢的在JS中获取任何类型的方法
function getType(entity){
    var x = Object.prototype.toString.call(entity)
    return x.split(" ")[1].split(']')[0].toLowerCase()
}
  • 我最喜欢的检查JS中任何类型的方法
function checkType(entity, type){
    return getType(entity) === type
}

-1

使用class.name。这也适用于function.name

class TestA {}
console.log(TestA.name); // "TestA"

function TestB() {}
console.log(TestB.name); // "TestB"

问题很明确地说class,不是实例。
qwertzguy
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.