Question Comment obtenir la classe d'un objet JavaScript?


J'ai créé un objet JavaScript, mais comment puis-je déterminer la classe de cet objet?

Je veux quelque chose de similaire à Java .getClass() méthode.


490
2017-08-08 18:11


origine


Réponses:


Il n'y a pas de contrepartie exacte à Java getClass() en JavaScript. Cela est principalement dû au fait que JavaScript est un langage basé sur prototype, par opposition à Java étant un basé sur la classe un.

En fonction de ce dont vous avez besoin getClass() car, il existe plusieurs options en JavaScript:

Quelques exemples:

function Foo() {}
var foo = new Foo();

typeof Foo;             // == "function"
typeof foo;             // == "object"

foo instanceof Foo;     // == true
foo.constructor.name;   // == "Foo"
Foo.name                // == "Foo"    

Foo.prototype.isPrototypeOf(foo);   // == true

Foo.prototype.bar = function (x) {return x+x;};
foo.bar(21);            // == 42

Note: si vous compilez votre code avec Uglify, cela changera les noms de classes non globaux. Pour éviter cela, Uglify a un --mangle param que vous pouvez définir sur false utilise gorgée ou grognement.


707
2017-08-08 18:20



obj.constructor.name

fonctionne dans la plupart des cas dans les navigateurs modernes, malgré Function.name n'étant pas officiellement ajouté à la norme avant ES6. Si l'objet est instancié avec var obj = new MyClass(), il retournera "MyClass" comme une chaîne.

Il renverra "Number" pour les nombres, "Array" pour les tableaux et "Function" pour les fonctions, etc. Il semble être assez fiable. Les seuls cas où il échoue sont si un objet est créé sans prototype, via Object.create( null )ou l'objet a été instancié à partir d'une fonction anonyme (non nommée).

Discutablement, obj.constructor.name est beaucoup plus intuitive que typeof, et pourrait être encapsulé dans une fonction pour gérer les cas impairs où constructor n'est pas défini (et pour gérer les références nulles).

Remarque: Un autre avantage de cette méthode est qu'elle fonctionne de manière intuitive à travers les limites du DOM plutôt que de comparer les objets constructeurs directement ou en utilisant instanceOf. La raison pour laquelle cela ne fonctionne pas comme il se peut, c'est qu'il y a en fait différentes instances de la fonction constructeur sur chaque DOM. Par conséquent, une comparaison d'objet sur leurs constructeurs ne fonctionnera pas.

Note 2: Assez curieusement, cette méthode semble renvoyer le nom de la fonction la plus utilisée dans une chaîne prototype, ce qui n'est malheureusement pas intuitif. Par exemple si B dérive prototypiquement de A et vous créez une nouvelle instance de B, b, b.constructor.name renvoie "A"! Donc c'est totalement à l'envers. Il fonctionne très bien pour les prototypes à un seul niveau et toutes les primitives, cependant.


200
2018-01-03 16:36



Cette fonction renvoie soit "undefined", "null", ou la "class" dans [object class] de Object.prototype.toString.call(someObject).

function getClass(obj) {
  if (typeof obj === "undefined")
    return "undefined";
  if (obj === null)
    return "null";
  return Object.prototype.toString.call(obj)
    .match(/^\[object\s(.*)\]$/)[1];
}

getClass("")   === "String";
getClass(true) === "Boolean";
getClass(0)    === "Number";
getClass([])   === "Array";
getClass({})   === "Object";
getClass(null) === "null";
// etc...

22
2017-08-09 05:53



Pour obtenir la "pseudo-classe", vous pouvez obtenir la fonction constructeur, en

obj.constructor

en supposant que constructor est défini correctement lorsque vous faites l'héritage - ce qui est par quelque chose comme:

Dog.prototype = new Animal();
Dog.prototype.constructor = Dog;

et ces deux lignes, ainsi que:

var woofie = new Dog()

fera woofie.constructor pointer vers Dog. Notez que Dog est une fonction de constructeur, et est un Function objet. Mais tu peux faire if (woofie.constructor === Dog) { ... }.

Si vous voulez obtenir le nom de la classe sous forme de chaîne, j'ai trouvé ce qui suit fonctionne bien:

http://blog.magnetiq.com/post/514962277/finding-out-class-names-of-javascript-objects

function getObjectClass(obj) {
    if (obj && obj.constructor && obj.constructor.toString) {
        var arr = obj.constructor.toString().match(
            /function\s*(\w+)/);

        if (arr && arr.length == 2) {
            return arr[1];
        }
    }

    return undefined;
}

Il obtient la fonction constructeur, la convertit en chaîne et extrait le nom de la fonction constructeur.

Notez que obj.constructor.nameaurait bien fonctionné, mais ce n'est pas standard. C'est sur Chrome et Firefox, mais pas sur IE, y compris IE 9 ou IE 10 RTM.


17
2017-10-04 14:55



Vous pouvez obtenir une référence à la fonction constructeur qui a créé l'objet en utilisant le propriété du constructeur:

function MyObject(){
}

var obj = new MyObject();
obj.constructor; // MyObject

Si vous devez confirmer le type d'un objet à l'exécution, vous pouvez utiliser le exemple de opérateur:

obj instanceof MyObject // true

7
2017-08-08 18:24



J'ai eu une situation de travailler générique maintenant et utilisé ceci:

class Test {
  // your class definition
}

nameByType = function(type){
  return type.prototype["constructor"]["name"];
};

console.log(nameByType(Test));

C'est la seule façon que j'ai trouvé pour obtenir le nom de classe par type d'entrée si vous n'avez pas une instance d'un objet.

(écrit en ES2017)

notation par points fonctionne également bien

console.log(Test.prototype.constructor.name); // returns "Test" 

4
2018-05-29 09:16



je trouve object.constructor.toString() revenir [object objectClass] dans IE, plutôt que function objectClass () {} retourné à Chome. Donc, je pense que le code http://blog.magnetiq.com/post/514962277/finding-out-class-names-of-javascript-objects peut ne pas fonctionner correctement dans IE.Et j'ai corrigé le code comme suit:

code:

var getObjectClass = function (obj) {
        if (obj && obj.constructor && obj.constructor.toString()) {

                /*
                 *  for browsers which have name property in the constructor
                 *  of the object,such as chrome 
                 */
                if(obj.constructor.name) {
                    return obj.constructor.name;
                }
                var str = obj.constructor.toString();
                /*
                 * executed if the return of object.constructor.toString() is 
                 * "[object objectClass]"
                 */

                if(str.charAt(0) == '[')
                {
                        var arr = str.match(/\[\w+\s*(\w+)\]/);
                } else {
                        /*
                         * executed if the return of object.constructor.toString() is 
                         * "function objectClass () {}"
                         * for IE Firefox
                         */
                        var arr = str.match(/function\s*(\w+)/);
                }
                if (arr && arr.length == 2) {
                            return arr[1];
                        }
          }
          return undefined; 
    };

3
2017-12-17 12:34



Pour les classes Javascript dans ES6, vous pouvez utiliser object.constructor. Dans la classe d'exemple ci-dessous getClass() La méthode renvoie la classe ES6 comme prévu:

var Cat = class {

    meow() {

        console.log("meow!");

    }

    getClass() {

        return this.constructor;

    }

}

var fluffy = new Cat();

...

var AlsoCat = fluffy.getClass();
var ruffles = new AlsoCat();

ruffles.meow();    // "meow!"

Si vous instanciez la classe du getClass méthode assurez-vous de l'envelopper entre parenthèses e.g. ruffles = new ( fluffy.getClass() )( args... );


3
2018-02-02 15:16