Vérifier si une valeur est un objet en JavaScript

1365

Comment vérifiez-vous si une valeur est un objet en JavaScript?

Danny Fox
la source
4
Une variable est une variable. Il peut faire référence à un objet. En outre, vous souhaiterez peut-être définir «objet» - comme le montrent les réponses et les commentaires, il existe différentes définitions contradictoires (par exemple, s'il nulls'agit d'un objet).
8
OP, IMO, vous devez accepter la réponse de @ Daan car c'est la meilleure solution et doit être répertoriée au-dessus des autres réponses afin qu'elle soit vue en premier. (
N'en déplaise
2
À mon humble avis, cela dépend vraiment de ce que vous (celui qui cherche une réponse à cette question) considérez un objet, et pourquoi vous le vérifiez. Cette question donne des réponses différentes si vous essayez de distinguer les tableaux (qui sont des objets) des autres objets ou si vous essayez de séparer les valeurs scalaires des "vecteurs". Et que null (c'est-à- dire un objet, selon le type de) ou les fonctions (qui sont des objets) soient exclus ou non, cela dépend vraiment de la raison pour laquelle vous le vérifiez. C'est pourquoi il y a tant de réponses et la plupart d'entre elles, dans leur contexte, sont correctes.
FrancescoMM
const isEmpty = thing => {typeof thing === "object"? ! chose || ! Object.keys (thing) .length:! Thing && thing! == 0};
Mayur S
1
Ce serait bien si vous pouviez commencer par dire ce que vous entendez exactement par "est un objet". (Ou, dites explicitement qu'une partie de la réponse que vous cherchez est de définir différentes significations populaires de "est un objet", puis de les différencier.) À défaut, tout le monde parle les uns après les autres.
Don Hatch

Réponses:

520

MISE À JOUR :

Cette réponse est incomplète et donne des résultats trompeurs . Par exemple, nullest également considéré de type objecten JavaScript, sans parler de plusieurs autres cas de bord. Suivez la recommandation ci-dessous et passez à l'autre "réponse la plus positive (et correcte!)" .


Réponse originale :

Essayez d'utiliser typeof(var)et / ou var instanceof something.

EDIT: Cette réponse donne une idée de la façon d'examiner les propriétés des variables, mais ce n'est pas une recette à l'épreuve des balles (après tout, il n'y a pas de recette du tout!) Pour vérifier si c'est un objet, loin de là. Étant donné que les gens ont tendance à chercher quelque chose à copier à partir d'ici sans faire de recherche, je leur recommande fortement de se tourner vers l'autre réponse la plus appréciée (et correcte!).

Michael Krelin - pirate
la source
208
typeofest un opérateur, donc pas besoin de ().
Yoshi
67
Oui, pas besoin. Je préfère juste ça comme ça.
Michael Krelin - hacker
150
@ MichaelKrelin-hacker: C'est dommage car cela déroute les gens .
RightSaidFred
11
@RightSaidFred, je n'ai aucune explication à cela, mais je ne suis absolument pas enclin à ajouter des parenthèses supplémentaires dans ces expressions :)
Michael Krelin - pirate informatique
117
Cette réponse est incorrecte. typeofrenvoie «objet» pour null, qui n'est pas un objet, et instanceofne fonctionne pas pour les objets créés à l'aide de Object.create(null).
Nikolai
1636

Si typeof yourVariable === 'object', c'est un objet ou null. Si vous voulez exclure null, faites-le typeof yourVariable === 'object' && yourVariable !== null.

Mandrin
la source
31
Les fonctions sont également des objets et doivent être incluses dans votre chèque.
JS_Riddler
4
Dans ce cas, serait yourVariable !== nullune meilleure pratique?
hippietrail
9
@RightSaidFred Semble typeof null == 'object'ne pas être corrigé dans ES6 . Ils ont dit:This proposal has been rejected. It was implemented in V8 but it turned out that it broke a lot of existing sites. In the spirit of One JavaScript this is not feasible.
Konstantin Smolyanin
2
@Orion la réponse simple est que les tableaux sont considérés comme des objets. Pour une réponse plus détaillée, vous devrez lire typeofcar il a quelques cas spéciaux qui n'ont pas nécessairement beaucoup de sens. Si vous essayez de faire la différence entre des tableaux et des objets qui ne sont pas des tableaux, alors vous ne voulez certainement pas utiliser typeof.
Matt Fenwick
8
@Tresdin La meilleure façon est d'exécuter Object.prototype.toString.call(yourVar), étant votreVar ce que vous devez inspecter. En cas de tableaux, Object.prototype.toString.call([1,2])retourne[object Array]
Jose Rui Santos
539

Définissons "objet" en Javascript . Selon les documents MDN , chaque valeur est soit un objet soit une primitive:

primitive, valeur primitive

Une donnée qui n'est pas un objet et qui n'a aucune méthode. JavaScript a 5 types de données primitifs: chaîne, nombre, booléen, null, non défini.

Qu'est-ce qu'une primitive?

  • 3
  • 'abc'
  • true
  • null
  • undefined

Qu'est-ce qu'un objet (c'est-à-dire pas une primitive)?

  • Object.prototype
  • tout descend de Object.prototype
    • Function.prototype
      • Object
      • Function
      • function C(){} - fonctions définies par l'utilisateur
    • C.prototype- la propriété prototype d'une fonction définie par l'utilisateur: ce n'est pas C le prototype
      • new C() - "nouveau" -ing une fonction définie par l'utilisateur
    • Math
    • Array.prototype
      • tableaux
    • {"a": 1, "b": 2} - objets créés en utilisant la notation littérale
    • new Number(3) - enveloppements autour des primitives
    • ... beaucoup d'autres choses ...
  • Object.create(null)
  • tout est descendu d'un Object.create(null)

Comment vérifier si une valeur est un objet

instanceof en soi ne fonctionnera pas, car il manque deux cas:

// oops:  isObject(Object.prototype) -> false
// oops:  isObject(Object.create(null)) -> false
function isObject(val) {
    return val instanceof Object; 
}

typeof x === 'object'ne fonctionnera pas, à cause des faux positifs ( null) et des faux négatifs (fonctions):

// oops: isObject(Object) -> false
function isObject(val) {
    return (typeof val === 'object');
}

Object.prototype.toString.call ne fonctionnera pas, en raison de faux positifs pour toutes les primitives:

> Object.prototype.toString.call(3)
"[object Number]"

> Object.prototype.toString.call(new Number(3))
"[object Number]"

J'utilise donc:

function isObject(val) {
    if (val === null) { return false;}
    return ( (typeof val === 'function') || (typeof val === 'object') );
}

La réponse de @ Daan semble également fonctionner:

function isObject(obj) {
  return obj === Object(obj);
}

car, selon les documents MDN :

Le constructeur d'objet crée un wrapper d'objet pour la valeur donnée. Si la valeur est nulle ou non définie, elle créera et renverra un objet vide, sinon, elle renverra un objet d'un type correspondant à la valeur donnée. Si la valeur est déjà un objet, elle renverra la valeur.


Une troisième façon qui semble fonctionner (pas sûr que ce soit 100%) est d'utiliser Object.getPrototypeOfce qui lève une exception si son argument n'est pas un objet:

// these 5 examples throw exceptions
Object.getPrototypeOf(null)
Object.getPrototypeOf(undefined)
Object.getPrototypeOf(3)
Object.getPrototypeOf('abc')
Object.getPrototypeOf(true)

// these 5 examples don't throw exceptions
Object.getPrototypeOf(Object)
Object.getPrototypeOf(Object.prototype)
Object.getPrototypeOf(Object.create(null))
Object.getPrototypeOf([])
Object.getPrototypeOf({})
Matt Fenwick
la source
22
obj === Object(obj)renvoie truepour les tableaux.
Onur Yıldırım
5
var x = []; console.log(x === Object(x)); // return true
Illuminateur
6
Les tableaux @Illuminator sont des objets en Javascript, comme je l'ai mentionné dans ma réponse.
Matt Fenwick
1
getPrototypeOfne fonctionne pas, par exemple, avec les proxys révoqués, qui sont des objets mais des lancers.
Oriol
2
Pourquoi ({}).toString.apply(obj) === '[object Object]'cela ne fait- il pas la distinction entre les tableaux et les objets qui ne sont pas des tableaux
MauricioJuanes
295

underscore.js fournit la méthode suivante pour savoir si quelque chose est vraiment un objet:

_.isObject = function(obj) {
  return obj === Object(obj);
};

MISE À JOUR

En raison d'un bogue précédent dans la V8 et d'une optimisation de micro vitesse mineure, la méthode se présente comme suit depuis underscore.js 1.7.0 (août 2014):

_.isObject = function(obj) {
  var type = typeof obj;
  return type === 'function' || type === 'object' && !!obj;
};
Daan
la source
57
En javascript, un tableau est également un objet, donc la plupart du temps vous voulez exclure le tableau:return obj === Object(obj) && Object.prototype.toString.call(obj) !== '[object Array]'
Daan
22
pourquoi voudriez-vous exclure un tableau? Ce sont des objets à part entière.
Nikolai
65
Parce que la plupart du temps vous voulez distinguer un {} d'un [] par exemple comme entrée dans une fonction
Daan
5
@Nickolai ..et pour l'itération à travers des objets imbriqués.
Ricky Boyce
6
Très bonne réponse. Poignées nullaussi. Doit être la réponse acceptée.
tiffon
180

Object.prototype.toString.call(myVar) retournera:

  • "[object Object]" si myVar est un objet
  • "[object Array]" si myVar est un tableau
  • etc.

Pour plus d'informations à ce sujet et pourquoi c'est une bonne alternative à typeof, consultez cet article .

Christophe
la source
12
J'ai récemment appris que typeof [] === 'object'-> true. C'est ce dont vous avez besoin pour cette méthode.
Jondlm
3
@Christophe Ne fait pas de distinction entre les primitives et les objets . Object.prototype.toString.call(3)-> "[object Number]". Object.prototype.toString.call(new Number(3))-> "[object Number]"
Matt Fenwick
3
@MattFenwick Je ne pense pas que ce soit le genre "d'objet" que le PO essaie d'identifier
Christophe
3
@Christophe pourquoi pensez-vous cela? À mon humble avis, en l'absence de toute autre définition donnée par le PO pour "objet", il me semble très raisonnable de choisir celle qui est utilisée de manière cohérente dans toutes les spécifications ECS.
Matt Fenwick
getType=function(obj){return Object.prototype.toString.call(obj).match(/\[object (\w+)\]/)[1];};
M. Polywhirl
117

Pour une simple vérification par rapport à Object ou Array sans appel de fonction supplémentaire (vitesse). Comme également affiché ici .

isArray ()

isArray = function(a) {
    return (!!a) && (a.constructor === Array);
};
console.log(isArray(        )); // false
console.log(isArray(    null)); // false
console.log(isArray(    true)); // false
console.log(isArray(       1)); // false
console.log(isArray(   'str')); // false
console.log(isArray(      {})); // false
console.log(isArray(new Date)); // false
console.log(isArray(      [])); // true

isObject () - Remarque: utilisez uniquement pour les littéraux d'objet, car il renvoie false pour les objets personnalisés, comme new Date ou new YourCustomObject.

isObject = function(a) {
    return (!!a) && (a.constructor === Object);
};
console.log(isObject(        )); // false
console.log(isObject(    null)); // false
console.log(isObject(    true)); // false
console.log(isObject(       1)); // false
console.log(isObject(   'str')); // false
console.log(isObject(      [])); // false
console.log(isObject(new Date)); // false
console.log(isObject(      {})); // true
zupa
la source
isObjectne fonctionne qu'avec des littéraux d'objets. Si je crée un type personnalisé, crée une instance du type et le teste, il renvoiefalse
WickyNilliams
3
@zupa: quoi !! un fait?
4
@ 3000 eh bien, si nous omettons la partie (!! a), elle se bloque, car null et undefined n'ont pas de constructeurs. (!! a) les filtre. Est-ce que ça répond à votre question?
zupa
2
@zupa @ 3000 Boolean(a)est plus long, mais beaucoup plus intuitif. N'utilisez simplement pas new Boolean(a): ( voici pourquoi )!
JayVee
10
Surpris, la meilleure réponse est si loin en bas de la page. Cela répond essentiellement à la question - serait-ce représenté dans JSON comme quelque chose commençant par un {caractère. Pour le cas du tableau, tant que vous n'avez pas besoin de prendre en charge IE <9, vous pouvez utiliser Array.isArray()pour déterminer si quelque chose est un tableau. Il passe tous les cas de test que vous avez fournis.
Kip
81

J'aime tout simplement:

function isObject (item) {
  return (typeof item === "object" && !Array.isArray(item) && item !== null);
}

Si l'élément est un objet JS, et ce n'est pas un tableau JS, et ce n'est pas null... si les trois s'avèrent vrais, revenez true. Si l'une des trois conditions échoue, le &&test sera court-circuité et falsesera renvoyé. Le nulltest peut être omis si vous le souhaitez (selon la façon dont vous l'utilisez null).

DOCS:

http://devdocs.io/javascript/operators/typeof

http://devdocs.io/javascript/global_objects/object

http://devdocs.io/javascript/global_objects/array/isarray

http://devdocs.io/javascript/global_objects/null

2540625
la source
3
Qu'en est-il de console.log (isObject (new Date ()))? Pourquoi une date devrait-elle être un objet mais pas un tableau?
schirrmacher
5
@macher Parce que new Date()renvoie un objet. D'un point de vue logique, un tableau n'est pas un objet - bien que JavaScript les traite et les signale comme tels. En pratique cependant, il n'est pas utile de les voir égaux, car ils ne le sont pas. Un objet n'a pas d' lengthattribut par exemple et il n'a pas de méthodes comme push (). Et parfois, vous voudrez peut-être donner à une fonction des paramètres surchargés, où vous devrez faire la différence entre un tableau ou un objet, surtout si d'autres paramètres dépendent de celui qui a été donné.
StanE
1
Les tableaux @StanE sont définitivement des objets. Vous ne savez pas pourquoi vous pensez que les objets ne peuvent pas avoir une lengthpropriété ni des méthodes comme push, Object.create(Array.prototype)est un contre-exemple trivial d'un objet non-tableau qui en a. Ce qui rend les tableaux spéciaux, c'est qu'ils sont des objets exotiques avec une méthode interne essentielle personnalisée [[DefineOwnProperty]], mais ce sont toujours des objets.
Oriol
4
@Oriol Je n'ai ni écrit que les tableaux ne sont pas des objets, ni écrit que les objets ne peuvent pas avoir de lengthpropriété (je voulais dire que les littéraux d'objet n'ont pas d' lengthattribut par défaut). J'ai écrit que les tableaux ne sont pas des objets d'un point de vue logique . Je parle de la logique du programme. Il est parfois nécessaire de vérifier si un tableau est un tableau "réel" et certainement pas un objet "réel". C'est pour ça Array.isArray(). Imaginez que vous ayez une fonction qui accepte un objet ou un tableau d'objets. La vérification d'un attribut ou d'une méthode spéciale est une mauvaise solution. La manière native est toujours meilleure.
StanE
2
typeof nullest "object", non "undefined".
2540625
80

Avec fonction Array.isArray:

function isObject(o) {
  return o !== null && typeof o === 'object' && Array.isArray(o) === false;
}

Sans fonction Array.isArray:

Juste surpris du nombre de votes positifs pour les mauvaises réponses 😮
Une seule réponse a réussi mes tests !!! Ici, j'ai créé ma version simplifiée:

function isObject(o) {
  return o instanceof Object && o.constructor === Object;
}

Quant à moi, c'est clair et simple, et ça marche! Voici mes tests:

console.log(isObject({}));             // Will return: true
console.log(isObject([]));             // Will return: false
console.log(isObject(null));           // Will return: false
console.log(isObject(/.*/));           // Will return: false
console.log(isObject(function () {})); // Will return: false

UNE FOIS DE PLUS: toutes les réponses ne réussissent pas ces tests !!! 🙈


Dans le cas où vous devez vérifier que l'objet est une instance d'une classe particulière, vous devez vérifier le constructeur avec votre classe particulière, comme:

function isDate(o) {
  return o instanceof Object && o.constructor === Date;
}

test simple:

var d = new Date();
console.log(isObject(d)); // Will return: false
console.log(isDate(d));   // Will return: true

En conséquence, vous aurez un code strict et robuste!


Si vous ne créerez pas des fonctions comme isDate, isError, isRegExp, etc vous pouvez envisager l' option d'utiliser ces fonctions généralisées:

function isObject(o) {
  return o instanceof Object && typeof o.constructor === 'function';
}

il ne fonctionnera pas correctement pour tous les cas de test mentionnés précédemment, mais il est assez bon pour tous les objets (simples ou construits).


isObjectne fonctionnera pas en cas de Object.create(null)cause de l'implémentation interne Object.createqui est expliquée ici mais vous pouvez l'utiliser isObjectdans une implémentation plus sophistiquée:

function isObject(o, strict = true) {
  if (o === null || o === undefined) {
    return false;
  }
  const instanceOfObject = o instanceof Object;
  const typeOfObject = typeof o === 'object';
  const constructorUndefined = o.constructor === undefined;
  const constructorObject = o.constructor === Object;
  const typeOfConstructorObject = typeof o.constructor === 'function';
  let r;
  if (strict === true) {
    r = (instanceOfObject || typeOfObject) && (constructorUndefined || constructorObject);
  } else {
    r = (constructorUndefined || typeOfConstructorObject);
  }
  return r;
};

Il existe déjà un package créé sur npm v1 basé sur cette implémentation! Et cela fonctionne pour tous les cas de test décrits précédemment! 🙂

V. Kovpak
la source
meilleure réponse! fonctionne pour de nombreux cas mentionnés ici
prêtre
Parce que cela renvoie false pour isObject (myDateObject), ce n'est pas une réponse à la question. Il ne dit pas si une variable est un objet, seulement si c'est un objet d'une classe spécifique. La question ici est pour une fonction générique qui renvoie vrai pour n'importe quel objet.
Yetanotherjosh
@Yetanotherjosh C'est une réponse en effet 🤓 vous avez mentionné le cas qui est décrit dans la réponse, et le point - vous devez utiliser isDatepour votreDateObject dans le but d'écrire du code robuste sinon vous aurez une isObjectméthode fragile .
V.Kovpak
@VladimirKovpak L'utilisation Datedans mon commentaire a été mal choisie car oui, la réponse en discute Date. Mais ce Daten'est qu'une des classes possibles infinies et le point est valable pour toute autre classe. Exemple: class Foo() { }; var x = new Foo(); isObject(x)retourne false. Je ne sais pas exactement quel est le cas d'utilisation de l'OP, mais il est facile de concevoir des scénarios dans lesquels il sera impossible de connaître toutes les classes possibles et de vérifier spécifiquement chacune d'elles .
Yetanotherjosh
@Yetanotherjosh J'ai mis à jour ma réponse. Et ajouté 1 cas de plus.
V.Kovpak
41

Oh mon Dieu! Je pense que cela pourrait être plus court que jamais, voyons ceci:

Code court et final

function isObject(obj)
{
    return obj != null && obj.constructor.name === "Object"
}

console.log(isObject({})) // returns true
console.log(isObject([])) // returns false
console.log(isObject(null)) // returns false

Expliqué

Types de retour

typeof JavaScript (y compris null) renvoie"object"

console.log(typeof null, typeof [], typeof {})

Vérifier leurs constructeurs

La vérification de leur constructorpropriété renvoie la fonction avec leurs noms.

console.log(({}).constructor) // returns a function with name "Object"
console.log(([]).constructor) // returns a function with name "Array"
console.log((null).constructor) //throws an error because null does not actually have a property

Présentation de Function.name

Function.namerenvoie un nom en lecture seule d'une fonction ou "anonymous"pour les fermetures.

console.log(({}).constructor.name) // returns "Object"
console.log(([]).constructor.name) // returns "Array"
console.log((null).constructor.name) //throws an error because null does not actually have a property

Remarque: à partir de 2018, Function.name peut ne pas fonctionner dans IE https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name#Browser_compatibility

Erisan Olasheni
la source
3
J'aime vraiment celui-ci, bref et précis. Pour autant que je puisse voir, cela échoue sur une seule chose. si obj = Object.create(null)et pourquoi vous le feriez quand même ...?
Julian Knight
29

OK, donnons-nous ce concept avant de répondre à votre question, dans les fonctions JavaScript sont Object, également null, Object, Arrays et même Date, donc comme vous le voyez, il n'y a pas de moyen simple comme typeof obj === 'object', donc tout ce qui est mentionné ci-dessus retournera vrai , mais il existe des moyens de le vérifier en écrivant une fonction ou en utilisant des frameworks JavaScript, OK:

Maintenant, imaginez que vous avez cet objet qui est un véritable objet (pas nul ou une fonction ou un tableau):

var obj = {obj1: 'obj1', obj2: 'obj2'};

JavaScript pur:

//that's how it gets checked in angular framework
function isObject(obj) {
  return obj !== null && typeof obj === 'object';
}

ou

//make sure the second object is capitalised 
function isObject(obj) {
   return Object.prototype.toString.call(obj) === '[object Object]';
}

ou

function isObject(obj) {
    return obj.constructor.toString().indexOf("Object") > -1;
}

ou

function isObject(obj) {
    return obj instanceof Object;
}

Vous pouvez simplement utiliser l'une de ces fonctions comme ci-dessus dans votre code en les appelant et cela retournera vrai si c'est un objet:

isObject(obj);

Si vous utilisez un framework JavaScript, ils ont généralement préparé ce genre de fonctions pour vous, ce sont quelques-unes d'entre elles:

jQuery:

 //It returns 'object' if real Object;
 jQuery.type(obj);

Angulaire:

angular.isObject(obj);

Souligner et Lodash:

//(NOTE: in Underscore and Lodash, functions, arrays return true as well but not null)
_.isObject(obj);
Alireza
la source
Vous souhaitez également vérifier qu'il ne s'agit pas d'un tableau. donc la fonction isObject (obj) {return obj! == null && typeof obj === 'object' &&! Array.isArray (obj); }
Matt Goo
Je suis d'accord avec vous, mais comme vous le voyez dans le commentaire, c'est comme ça que ça se fait dans angularJs et je le mentionne dans le commentaire devant la fonction, ils comptent le tableau comme un objet ... regardez ici pour plus d'informations: docs .angularjs.org / api / ng / function / angular.isObject
Alireza
24

Cela dépend de ce que vous entendez par «est un objet». Si vous voulez tout ce qui n'est pas une primitive , c'est-à-dire des choses sur lesquelles vous pouvez définir de nouvelles propriétés, cela devrait faire l'affaire:

function isAnyObject(value) {
    return value != null && (typeof value === 'object' || typeof value === 'function');
}

Il exclut les primitives (nombres simples / NaN/ Infinity, chaînes simples, symboles, true/ false, undefinedet null) mais doit renvoyer true pour tout le reste (y compris Number, Booleanet les Stringobjets). Notez que JS ne définit pas quels objets "hôte", tels que windowou console, doivent retourner lorsqu'ils sont utilisés avec typeof, donc ceux-ci sont difficiles à couvrir avec une vérification comme celle-ci.

Si vous voulez savoir si quelque chose est un objet "simple", c'est-à-dire qu'il a été créé en tant que littéral {}ou avec Object.create(null), vous pouvez le faire:

function isPlainObject(value) {
    if (Object.prototype.toString.call(value) !== '[object Object]') {
        return false;
    } else {
        var prototype = Object.getPrototypeOf(value);
        return prototype === null || prototype === Object.prototype;
    }
}

Edit 2018 : Parce que Symbol.toStringTagpermet désormais de personnaliser la sortie de Object.prototype.toString.call(...), la isPlainObjectfonction ci-dessus peut revenir falsedans certains cas même lorsque l'objet a commencé sa vie en tant que littéral. Sans doute, par convention, un objet avec une balise de chaîne personnalisée n'est plus exactement un objet ordinaire, mais cela a encore brouillé la définition de ce qu'est même un objet ordinaire en Javascript.

dernier enfant
la source
Pourquoi typeof === 'fonction' est-il considéré comme un objet? Une fonction n'est pas un objet, n'est-ce pas? "new myFunc ()" deviendra un objet, oui, mais une simple fonction?
StanE
Non, chaque fonction est un objet en Javascript, quelle que soit la façon dont il a été créé. Vous pouvez leur attribuer des propriétés (à moins qu'elles ne soient figées), elles le sont instanceof Object, deux littéraux de fonction identiques ne sont pas strictement égaux, ils sont passés par référence, etc.
dernier enfant
21

Mon Dieu, trop de confusion dans les autres réponses.

Réponse courte

typeof anyVar == 'object' && anyVar instanceof Object && !(anyVar instanceof Array)

Pour tester cela, exécutez simplement les instructions suivantes dans la console Chrome.

Cas 1.

var anyVar = {};
typeof anyVar == 'object' && anyVar instanceof Object && !(anyVar instanceof Array) // true

Cas 2.

anyVar = [];
typeof anyVar == 'object' && anyVar instanceof Object && !(anyVar instanceof Array) // false

Cas 3.

anyVar = null;
typeof anyVar == 'object' && anyVar instanceof Object && !(anyVar instanceof Array); // false

Explication

D'accord, décomposons

typeof anyVar == 'object'est retourné vrai de trois candidats - [], {} and null,

anyVar instanceof Object réduit ces candidats à deux - [], {}

!(anyVar instanceof Array) se réduit à un seul - {}

Rouleaux de tambour s'il vous plaît!

Par cela, vous avez peut-être déjà appris à vérifier Array en Javascript.

kushalvm
la source
2
Il convient de noter que cela renvoie également false(comme souhaité) quand anyVarest une fonction.
Jamie Birch du
18

La façon la plus raisonnable de vérifier le type d'une valeur semble être l' typeofopérateur. Le seul problème est qu'il est horriblement cassé:

  • Il renvoie "object"pour null, qui appartient au type Null.
  • Il renvoie "function"pour les objets appelables, qui appartiennent au type d'objet.
  • Il peut retourner (presque) tout ce qu'il veut pour des objets non standard non appelables. Par exemple, IE semblait aimer "unknown". Les seuls résultats interdits sont "function"les types primitifs.

typeofn'est fiable que pour les non nullprimitifs. Ainsi, un moyen de vérifier si une valeur est un objet serait de s'assurer que la chaîne retournée par typeofne correspond pas à une primitive, et que l'objet ne l'est pas null. Cependant, le problème est qu'une future norme pourrait introduire un nouveau type primitif, et notre code le considérerait comme un objet. Les nouveaux types n'apparaissent pas fréquemment, mais par exemple ECMAScript 6 a introduit le type Symbol.

Par conséquent, au lieu de typeof, je ne recommande que des approches dont le résultat varie selon que la valeur est un objet ou non. Ce qui suit se veut un

Liste complète mais non exhaustive des moyens appropriés pour tester si une valeur appartient au type d'objet.

  • Object constructeur

    Le Objectconstructeur contraint l'argument passé à un objet. S'il s'agit déjà d'un objet, le même objet est renvoyé.

    Par conséquent, vous pouvez l'utiliser pour contraindre la valeur à un objet et comparer strictement cet objet avec la valeur d'origine.

    La fonction suivante nécessite ECMAScript 3, qui a introduit ===:

    function isObject(value) { /* Requires ECMAScript 3 or later */
      return Object(value) === value;
    }

    J'aime cette approche car elle est simple et auto-descriptive, et une vérification analogue fonctionnera également pour les booléens, les nombres et les chaînes. Cependant, sachez que cela repose sur le fait que le monde Objectn'est pas masqué ni modifié.

  • Constructeurs

    Lorsque vous instanciez un constructeur, il peut renvoyer une valeur différente de l'instance qui vient d'être créée. Mais cette valeur sera ignorée sauf s'il s'agit d'un objet.

    La fonction suivante nécessite ECMAScript 3, qui permettait aux constructeurs de renvoyer des non-objets. Avant ECMAScript 3, une erreur s'est produite, mais les trydéclarations n'existaient pas à l'époque.

    function isObject(value) { /* Requires ECMAScript 3 or later */
      return new function() { return value; }() === value;
    }

    Bien qu'un peu moins simple que l'exemple précédent, celui-ci ne repose sur aucune propriété globale, et peut donc être le plus sûr.

  • this valeur

    Les anciennes spécifications ECMAScript exigeaient que la thisvaleur soit un objet. ECMAScript 3 introduit Function.prototype.call, qui permettait d'appeler une fonction avec une thisvaleur arbitraire , mais contrainte à un objet.

    ECMAScript 5 a introduit un mode strict qui a supprimé ce comportement, mais en mode bâclé, nous pouvons toujours (mais sans doute pas) y compter.

    function isObject(value) { /* Requires ECMAScript 3 or later in sloppy mode */
      return function() { return this === value; }.call(value);
    }
  • [[Prototype]]

    Tous les objets ordinaires ont un emplacement interne appelé [[Prototype]], dont la valeur détermine de quel autre objet il hérite. La valeur ne peut être qu'un objet ou null. Par conséquent, vous pouvez essayer de créer un objet qui hérite de la valeur souhaitée et vérifier si cela a fonctionné.

    Les deux Object.createet Object.getPrototypeOfnécessitent ECMAScript 5.

    function isObject(value) { /* Requires ECMAScript 5 or later */
      try {
        Object.create(value);
        return value !== null;
      } catch(err) {
        return false;
      }
    }
    function isObject(value) { /* Requires ECMAScript 5 or later */
      function Constructor() {}
      Constructor.prototype = value;
      return Object.getPrototypeOf(new Constructor()) === value;
    }
  • Quelques nouveaux modes ECMAScript 6

    ECMAScript 6 introduit de nouvelles façons indirectes de vérifier si une valeur est un objet. Ils utilisent l'approche vue précédemment pour transmettre la valeur à un code qui nécessite un objet, enveloppé dans une tryinstruction pour détecter les erreurs. Quelques exemples cachés, qui ne valent pas la peine d'être commentés


Remarque: J'ai intentionnellement ignoré certaines approches comme Object.getPrototypeOf(value)(ES5) et les Reflectméthodes (ES6) car elles appellent des méthodes internes essentielles qui pourraient faire des choses désagréables, par exemple si valuec'est un proxy. Pour des raisons de sécurité, mes exemples ne font référence que valuesans y accéder directement.

Oriol
la source
2
"Seule ma réponse et celle de Daan sont entièrement correctes." est un peu présomptueux étant donné que je suis entièrement en désaccord avec vos deux premières phrases.
zzzzBov
1
@zzzzBov Eh bien, j'ai regardé toutes les réponses et elles ne garantissent pas toujours de renvoyer la bonne réponse, sauf la mienne et celle de Daan. Je peux donner des contre-exemples reproductibles à la plupart d'entre eux. Les autres recommandent de vérifier si typeof renvoie "fonction" ou "objet", mais comme je l'ai expliqué, la spécification permet d'autres résultats pour certains objets. La réponse de Matt Fenwick contient la même réponse correcte que celle de Daan, mais contient également des réponses incorrectes.
Oriol
1
Je ne suis pas d'accord avec l'hypothèse selon laquelle votre réponse est "tout à fait correcte", faisant valoir que d'autres "ne s'assurent pas de toujours renvoyer la bonne réponse" ne réfute en rien ma position. De plus, la question ne fait aucune réclamation concernant quelle entrée devrait produire quelle sortie.
zzzzBov
1
@zzzzBov La question demande comment vérifier si quelque chose est un objet. ECMAScript définit ce qu'est un objet, donc j'utilise cette définition. Je ne vois aucune autre interprétation raisonnable. Les réponses qui font d'autres choses (comme exclure des tableaux) peuvent être utiles dans certaines circonstances, mais elles ne vérifient pas si quelque chose est un objet.
Oriol
@Oriol Peut-être pourriez-vous fournir une réponse à cette question Pourquoi n'y a-t-il pas une méthode intégrée en JavaScript pour vérifier si un objet est un objet simple? ?
guest271314
15

Essaye ça

if (objectName instanceof Object == false) {
  alert('Not an object');
}
else {
  alert('An object');
}
Talha
la source
14
Pourquoi vous testez les booléens?
jkutianski
5
Il manque deux cas: Object.prototype instanceof Object-> faux. Object.create(null) instanceof Object-> faux.
Matt Fenwick
et les dates? new Date() instanceof Object => true
mauron85
13

Fonctions prêtes à l'emploi pour la vérification

function isObject(o) {
  return null != o && 
    typeof o === 'object' && 
    Object.prototype.toString.call(o) === '[object Object]';
}

function isDerivedObject(o) {
  return !isObject(o) && 
    null != o && 
    (typeof o === 'object' || typeof o === 'function') &&
    /^\[object /.test(Object.prototype.toString.call(o));
}

// Loose equality operator (==) is intentionally used to check
// for undefined too

// Also note that, even null is an object, within isDerivedObject
// function we skip that and always return false for null

Explication

  • En Javascript, null, Object, Array, Dateet functions sont tous les objets. Bien, nullest un peu artificiel. Donc, il vaut mieux vérifier le nullpremier, pour détecter qu'il n'est pas nul.

  • Vérification des typeof o === 'object'garanties qui osont un objet. Sans cette vérification, cela Object.prototype.toStringn'aurait aucun sens, car il retournerait un objet pour tout, même pour undefinedet null! Par exemple: toString(undefined)retourne [object Undefined]!

    Après typeof o === 'object'vérification, toString.call (o) est une bonne méthode pour vérifier si oun objet, un objet dérivé comme Array, Dateou function.

  • En isDerivedObjectfonction, il vérifie si oest une fonction. Parce que fonctionner aussi un objet, c'est pourquoi il est là. Si ce n'est pas le cas, la fonction retournera false. Exemple: isDerivedObject(function() {})retournerait false, mais maintenant il revient true.

  • On peut toujours changer la définition de ce qu'est un objet. Ainsi, on peut modifier ces fonctions en conséquence.


Les tests

function isObject(o) {
  return null != o && 
    typeof o === 'object' && 
    Object.prototype.toString.call(o) === '[object Object]';
}

function isDerivedObject(o) {
  return !isObject(o) && 
    null != o && 
    (typeof o === 'object' || typeof o === 'function') &&
    /^\[object /.test(Object.prototype.toString.call(o));
}

// TESTS

// is null an object?

console.log(
  'is null an object?', isObject(null)
);

console.log(
  'is null a derived object?', isDerivedObject(null)
);

// is 1234 an object?

console.log(
  'is 1234 an object?', isObject(1234)
);

console.log(
  'is 1234 a derived object?', isDerivedObject(1234)
);

// is new Number(1234) an object?

console.log(
  'is new Number(1234) an object?', isObject(new Number(1234))
);

console.log(
  'is new Number(1234) a derived object?', isDerivedObject(1234)
);

// is function object an object?

console.log(
  'is (new (function (){})) an object?', 
  isObject((new (function (){})))
);

console.log(
  'is (new (function (){})) a derived object?', 
  isObject((new (function (){})))
);

// is {} an object?

console.log(
  'is {} an object?', isObject({})
);

console.log(
  'is {} a derived object?', isDerivedObject({})
);

// is Array an object?

console.log(
  'is Array an object?',
  isObject([])
)

console.log(
  'is Array a derived object?',
  isDerivedObject([])
)

// is Date an object?

console.log(
  'is Date an object?', isObject(new Date())
);

console.log(
  'is Date a derived object?', isDerivedObject(new Date())
);

// is function an object?

console.log(
  'is function an object?', isObject(function(){})
);

console.log(
  'is function a derived object?', isDerivedObject(function(){})
);

Inanc Gumus
la source
13

Si vous souhaitez vérifier si le prototypepour objectprovient uniquement de Object. Filtres à String, Number, Array, Arguments, etc.

function isObject (n) {
  return Object.prototype.toString.call(n) === '[object Object]';
}

Ou comme une fonction de flèche à expression unique (ES6 +)

const isObject = n => Object.prototype.toString.call(n) === '[object Object]'
sasi
la source
1
c'est le meilleur moyen mais je le return Object.prototype.toString.call(n) === '[object Object]'
rendrais
1
Vous pouvez également retirer le nullchèque, carObject.prototype.toString.call(null) === '[object Null]'
Gust van de Wal
12
var a = [1]
typeof a //"object"
a instanceof Object //true
a instanceof Array //true

var b ={a: 1}
b instanceof Object //true
b instanceof Array //false

var c = null
c instanceof Object //false
c instanceof Array //false

On m'a demandé de fournir plus de détails. La façon la plus claire et compréhensible de vérifier si notre variable est un objet l'est typeof myVar. Il renvoie une chaîne avec un type (par exemple "object", "undefined").

Malheureusement, Array et null ont également un type object. Pour ne prendre que des objets réels, il est nécessaire de vérifier la chaîne d'héritage à l'aide de l' instanceofopérateur. Il éliminera null, mais Array a un objet dans la chaîne d'héritage.

La solution est donc:

if (myVar instanceof Object && !(myVar instanceof Array)) {
  // code for objects
}
Kania
la source
/./ instanceof Object //true
yckart
11

Un peu tard ... pour les "objets simples" (je veux dire, comme {'x': 5, 'y': 7}), j'ai ce petit extrait:

function isPlainObject(o) {
   return ((o === null) || Array.isArray(o) || typeof o == 'function') ?
           false
          :(typeof o == 'object');
}

Il génère la sortie suivante:

console.debug(isPlainObject(isPlainObject)); //function, false
console.debug(isPlainObject({'x': 6, 'y': 16})); //literal object, true
console.debug(isPlainObject(5)); //number, false
console.debug(isPlainObject(undefined)); //undefined, false
console.debug(isPlainObject(null)); //null, false
console.debug(isPlainObject('a')); //string, false
console.debug(isPlainObject([])); //array?, false
console.debug(isPlainObject(true)); //bool, false
console.debug(isPlainObject(false)); //bool, false

Ça marche toujours pour moi. If renverra "true" uniquement si le type de "o" est "object", mais pas de null, ni de tableau, ni de fonction. :)

Emilio Grisolía
la source
Comme mentionné dans les réponses précédentes, votre approche échouera dans le cas de l'objet Date.
Grzegorz Pawlik
9

lodash a isPlainObject , qui pourrait être ce que beaucoup de personnes qui visitent cette page recherchent. Elle retourne false lorsqu'elle donne une fonction ou un tableau.

Tapoter
la source
Parfait! Je savais _.isObjectce qui correspond à ce que JS considère comme un objet. Mais ce dont j'ai généralement besoin, c'est de faire la différence entre, par exemple, un littéral objet et un tableau, ce qui est exactement ce qui _.isPlainObjectme permet de faire.
lime
9

Cela fonctionnera. Il s'agit d'une fonction qui renvoie vrai, faux ou éventuellement nul.

const isObject = obj => obj && obj.constructor && obj.constructor === Object;

console.log(isObject({})); // true
console.log(isObject([])); // false
console.log(isObject(new Function)); // false
console.log(isObject(new Number(123))); // false
console.log(isObject(null)); // null

pizzarob
la source
2
@SeregPie À l'avenir, vous devriez vous abstenir de modifier le code dans les réponses. Dans l'état actuel des choses, lors du test, j'ai obtenu nullle résultat du test final plutôt que false. Voir Quand dois-je apporter des modifications au code?
Nick
9

Puisqu'il semble y avoir beaucoup de confusion sur la façon de gérer correctement ce problème, je vais laisser mes 2 cents (cette réponse est conforme aux spécifications et produit des résultats corrects en toutes circonstances):

Test des primitives: undefined null boolean string number

function isPrimitive(o){return typeof o!=='object'||null}

Un objet n'est pas une primitive:

function isObject(o){return !isPrimitive(o)}

Ou bien:

function isObject(o){return o instanceof Object}
function isPrimitive(o){return !isObject(o)}

Test pour n'importe quelle baie:

const isArray=(function(){
    const arrayTypes=Object.create(null);
    arrayTypes['Array']=true;
    arrayTypes['Int8Array']=true;
    arrayTypes['Uint8Array']=true;
    arrayTypes['Uint8ClampedArray']=true;
    arrayTypes['Int16Array']=true;
    arrayTypes['Uint16Array']=true;
    arrayTypes['Int32Array']=true;
    arrayTypes['Uint32Array']=true;
    arrayTypes['BigInt64Array']=true;
    arrayTypes['BigUint64Array']=true;
    arrayTypes['Float32Array']=true;
    arrayTypes['Float64Array']=true;
    return function(o){
        if (!o) return false;
        return !isPrimitive(o)&&!!arrayTypes[o.constructor.name];
    }
}());

Test d'objet à l'exclusion de: Date RegExp Boolean Number String Functiontout tableau

const isObjectStrict=(function(){
    const nativeTypes=Object.create(null);
    nativeTypes['Date']=true;
    nativeTypes['RegExp']=true;
    nativeTypes['Boolean']=true;
    nativeTypes['Number']=true;
    nativeTypes['String']=true;
    nativeTypes['Function']=true;
    return function(o){
        if (!o) return false;
        return !isPrimitive(o)&&!isArray(o)&&!nativeTypes[o.constructor.name];
    }
}());
c7x43t
la source
8

Quand tout le reste échoue, j'utilise ceci:

var isObject = function(item) {
   return item.constructor.name === "Object";
}; 
Michal
la source
1
Pourquoi la comparaison de chaînes, pourquoi pas simplement item.constructor === Object?
K3 --- rnc
nulllève une exceptionUncaught TypeError: Cannot read property 'constructor' of null(…)
Vitim.us
@rounce J'ai l'intention de prendre en charge les anciennes versions d'IE, pourquoi cela ne fonctionne-t-il pas dans IE? À cause de indexOfou à cause de constructor.name?
Jankapunkt le
8

La bibliothèque fonctionnelle Ramda a une fonction merveilleuse pour détecter les types JavaScript.

Paraphraser la fonction complète :

function type(val) {
  return val === null      ? 'Null'      :
         val === undefined ? 'Undefined' :
         Object.prototype.toString.call(val).slice(8, -1);
}

J'ai dû rire quand j'ai réalisé à quel point la solution était simple et belle.

Exemple d'utilisation de la documentation Ramda :

R.type({}); //=> "Object"
R.type(1); //=> "Number"
R.type(false); //=> "Boolean"
R.type('s'); //=> "String"
R.type(null); //=> "Null"
R.type([]); //=> "Array"
R.type(/[A-z]/); //=> "RegExp"
R.type(() => {}); //=> "Function"
R.type(undefined); //=> "Undefined"
DaveGauer
la source
8

Après avoir lu et essayer beaucoup d'implémentations, j'ai remarqué que très peu de gens essaient de vérifier les valeurs comme JSON, Math, documentou des objets avec des chaînes prototypes plus de 1 étape.

Au lieu de vérifier la typeofvariable de notre variable et de pirater ensuite les cas de bord, j'ai pensé qu'il serait préférable que la vérification soit aussi simple que possible pour éviter d'avoir à refactoriser quand de nouvelles primitives ou objets natifs ont été ajoutés qui s'inscrivent comme typeof`` objet '.

Après tout, l' typeofopérateur vous dira si quelque chose est un objet pour JavaScript , mais la définition JavaScript d'un objet est trop large pour la plupart des scénarios du monde réel (par exemple typeof null === 'object'). Vous trouverez ci-dessous une fonction qui détermine si la variable vest un objet en répétant essentiellement deux vérifications:

  1. Une boucle est démarrée qui se poursuit tant que la version chaîne de vest '[object Object]'.
    Je voulais que le résultat de la fonction soit exactement comme les journaux ci-dessous, c'est donc le seul critère "d'objectivité" avec lequel je me suis retrouvé. En cas d'échec, la fonction renvoie immédiatement false.
  2. vest remplacé par le prochain prototype de la chaîne avec v = Object.getPrototypeOf(v), mais aussi directement évalué après. Lorsque la nouvelle valeur de vest null, cela signifie que chaque prototype, y compris le prototype racine (qui pourrait très bien être le seul prototype à l'intérieur de la chaîne) a passé la vérification dans la boucle while et nous pouvons retourner vrai. Sinon, une nouvelle itération commence.

function isObj (v) {
  while (     Object.prototype.toString.call(v) === '[object Object]')
  if    ((v = Object.getPrototypeOf(v))         === null)
  return true
  return false
}

console.log('FALSE:')
console.log('[]                   -> ', isObj([]))
console.log('null                 -> ', isObj(null))
console.log('document             -> ', isObj(document))
console.log('JSON                 -> ', isObj(JSON))
console.log('function             -> ', isObj(function () {}))
console.log('new Date()           -> ', isObj(new Date()))
console.log('RegExp               -> ', isObj(/./))

console.log('TRUE:')
console.log('{}                   -> ', isObj({}))
console.log('new Object()         -> ', isObj(new Object()))
console.log('new Object(null)     -> ', isObj(new Object(null)))
console.log('new Object({})       -> ', isObj(new Object({foo: 'bar'})))
console.log('Object.prototype     -> ', isObj(Object.prototype))
console.log('Object.create(null)  -> ', isObj(Object.create(null)))
console.log('Object.create({})    -> ', isObj(Object.create({foo: 'bar'})))
console.log('deep inheritance     -> ', isObj(Object.create(Object.create({foo: 'bar'}))))

Gust van de Wal
la source
6
if(typeof value === 'object' && value.constructor === Object)
{
    console.log("This is an object");
}
Mahak Choudhary
la source
1
Si valuec'est nullcela va jeter une erreur ...
Gershom
Et bien sûr, ce sera falsepour l'objet Object.assign({}, {constructor: null}).
user4642212
6

Si vous souhaitez explicitement vérifier si la valeur donnée est {}.

function isObject (value) {
 return value && typeof value === 'object' && value.constructor === Object;
}
Carlos
la source
6
const isObject = function(obj) {
  const type = typeof obj;
  return type === 'function' || type === 'object' && !!obj;
};

!!objest un raccourci pour vérifier si elle objest véridique (pour filtrer null)

Ira
la source
6

C'est une vieille question mais j'ai pensé laisser ça ici. La plupart des gens vérifient si la variable {}signifie une paire valeur / clé et non quelle est la construction de soulignement que JavaScript utilise pour une chose donnée, car pour être honnête, la plupart des éléments de JavaScript sont un objet. Donc, retirez cela du chemin. Si tu fais...

let x = function() {}
typeof x === 'function' //true
x === Object(x) // true
x = []
x === Object(x) // true

// also
x = null
typeof null // 'object'

La plupart du temps, ce que nous voulons, c'est savoir si nous avons un objet ressource d'une API ou notre appel de base de données renvoyé par l'ORM. On peut alors tester si ce n'est pas un Array, n'est pas null, n'est pas typeof 'function', et est unObject

// To account also for new Date() as @toddmo pointed out

x instanceof Object && x.constructor === Object

x = 'test' // false
x = 3 // false
x = 45.6 // false
x = undefiend // false
x = 'undefiend' // false
x = null // false
x = function(){} // false
x = [1, 2] // false
x = new Date() // false
x = {} // true
Gilbert
la source
apparaît truepournew Date()
toddmo
1
@toddmo merci de l'avoir signalé. Maintenant, l'exemple de code retourne faux pournew Date()
Gilbert
4

Ce que j'aime utiliser c'est ceci

function isObject (obj) {
  return typeof(obj) == "object" 
        && !Array.isArray(obj) 
        && obj != null 
        && obj != ""
        && !(obj instanceof String)  }

Je pense que dans la plupart des cas, une date doit passer le contrôle en tant qu'objet, donc je ne filtre pas les dates

JohnPan
la source
4

j'ai trouvé une "nouvelle" façon de faire juste ce genre de vérification de type à partir de cette question SO: Pourquoi instanceof retourne faux pour certains littéraux?

à partir de cela, j'ai créé une fonction pour la vérification de type comme suit:

function isVarTypeOf(_var, _type){
    try {
        return _var.constructor === _type;
    } catch(ex) {
        return false;         //fallback for null or undefined
    }
}

alors vous pouvez simplement faire:

console.log(isVarTypeOf('asdf', String));   // returns true
console.log(isVarTypeOf(new String('asdf'), String));   // returns true
console.log(isVarTypeOf(123, String));   // returns false
console.log(isVarTypeOf(123, Number));   // returns true
console.log(isVarTypeOf(new Date(), String));   // returns false
console.log(isVarTypeOf(new Date(), Number));   // returns false
console.log(isVarTypeOf(new Date(), Date));   // returns true
console.log(isVarTypeOf([], Object));   // returns false
console.log(isVarTypeOf([], Array));   // returns true
console.log(isVarTypeOf({}, Object));   // returns true
console.log(isVarTypeOf({}, Array));   // returns false
console.log(isVarTypeOf(null, Object));   // returns false
console.log(isVarTypeOf(undefined, Object));   // returns false
console.log(isVarTypeOf(false, Boolean));   // returns true

ceci est testé sur Chrome 56, Firefox 52, Microsoft Edge 38, Internet Explorer 11, Opera 43

edit:
si vous voulez également vérifier si une variable est nulle ou non définie, vous pouvez utiliser ceci à la place:

function isVarTypeOf(_var, _type){
    try {
        return _var.constructor === _type;
    } catch(ex) {
        return _var == _type;   //null and undefined are considered the same
        // or you can use === if you want to differentiate them
    }
}

var a = undefined, b = null;
console.log(isVarTypeOf(a, undefined)) // returns true
console.log(isVarTypeOf(b, undefined)) // returns true
console.log(isVarTypeOf(a, null)) // returns true

mise à jour du commentaire de inanc: défi accepté: D

si vous voulez perdre des objets de comparaison, vous pouvez essayer de cette façon:

function isVarTypeOf(_var, _type, looseCompare){
    if (!looseCompare){
        try {
            return _var.constructor === _type;
        } catch(ex){
            return _var == _type;
        }
    } else {
        try{
            switch(_var.constructor){
                case Number:
                case Function:
                case Boolean:
                case Symbol:
                case Date:
                case String:
                case RegExp:
                    // add all standard objects you want to differentiate here
                    return _var.constructor === _type;
                case Error:
                case EvalError:
                case RangeError:
                case ReferenceError:
                case SyntaxError:
                case TypeError:
                case URIError:
                    // all errors are considered the same when compared to generic Error
                    return (_type === Error ? Error : _var.constructor) === _type;
                case Array:
                case Int8Array:
                case Uint8Array:
                case Uint8ClampedArray:
                case Int16Array:
                case Uint16Array:
                case Int32Array:
                case Uint32Array:
                case Float32Array:
                case Float64Array:
                    // all types of array are considered the same when compared to generic Array
                    return (_type === Array ? Array : _var.constructor) === _type;
                case Object:
                default:
                    // the remaining are considered as custom class/object, so treat it as object when compared to generic Object
                    return (_type === Object ? Object : _var.constructor) === _type;
            }
        } catch(ex){
            return _var == _type;   //null and undefined are considered the same
            // or you can use === if you want to differentiate them
        }
    }
}

de cette façon, vous pouvez faire comme le commentaire de inanc:

isVarTypeOf(new (function Foo(){}), Object); // returns false
isVarTypeOf(new (function Foo(){}), Object, true); // returns true

ou

Foo = function(){};
Bar = function(){};
isVarTypeOf(new Foo(), Object);   // returns false
isVarTypeOf(new Foo(), Object, true);   // returns true
isVarTypeOf(new Bar(), Foo, true);   // returns false
isVarTypeOf(new Bar(), Bar, true);   // returns true
isVarTypeOf(new Bar(), Bar);    // returns true
am05mhz
la source
Cela ne peut pas détecter si une nouvelle classe est un objet. isVarTypeOf (new (fonction Foo () {}), Object) // Cela renvoie false au lieu de true. Voir ma réponse ci-dessous pour une vérification appropriée.
Inanc Gumus
Cependant, vous pouvez utiliser instanceofpour rechercher des objets. Pourtant, ce n'est pas une science exacte.
Inanc Gumus
@inanc, eh bien c'est parce que new Foo()retourne un Fooobjet, comme cela new String()retourne un Stringobjet, ou new Date()retourne un Dateobjet, vous pouvez Foo = function(){}; isVarTypeOf(new Foo(), Foo);aussi faire
am05mhz
Oui, c'est ce que je dis en fait: vous ne vérifiez pas si c'est un objet en ce moment.
Inanc Gumus
@inanc Cheers, je cherchais un moyen de faire une vérification de type (pas seulement un objet), je suis arrivé à cette page et à l'autre page, puis je suis trop excité d'avoir oublié le contexte de cette question, ma mauvaise :)
am05mhz