Comment vérifiez-vous si une valeur est un objet en JavaScript?
javascript
object
types
javascript-objects
Danny Fox
la source
la source
null
s'agit d'un objet).Réponses:
MISE À JOUR :
Cette réponse est incomplète et donne des résultats trompeurs . Par exemple,
null
est également considéré de typeobject
en 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 / ouvar 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!).
la source
typeof
est un opérateur, donc pas besoin de()
.typeof
renvoie «objet» pour null, qui n'est pas un objet, etinstanceof
ne fonctionne pas pour les objets créés à l'aide deObject.create(null)
.Si
typeof yourVariable === 'object'
, c'est un objet ou null. Si vous voulez exclure null, faites-letypeof yourVariable === 'object' && yourVariable !== null
.la source
yourVariable !== null
une meilleure pratique?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.
typeof
car 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 utilisertypeof
.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]
Définissons "objet" en Javascript . Selon les documents MDN , chaque valeur est soit un objet soit une primitive:
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
Object.prototype
Function.prototype
Object
Function
function C(){}
- fonctions définies par l'utilisateurC.prototype
- la propriété prototype d'une fonction définie par l'utilisateur: ce n'est pasC
le prototypenew C()
- "nouveau" -ing une fonction définie par l'utilisateurMath
Array.prototype
{"a": 1, "b": 2}
- objets créés en utilisant la notation littéralenew Number(3)
- enveloppements autour des primitivesObject.create(null)
Object.create(null)
Comment vérifier si une valeur est un objet
instanceof
en soi ne fonctionnera pas, car il manque deux cas:typeof x === 'object'
ne fonctionnera pas, à cause des faux positifs (null
) et des faux négatifs (fonctions):Object.prototype.toString.call
ne fonctionnera pas, en raison de faux positifs pour toutes les primitives:J'utilise donc:
La réponse de @ Daan semble également fonctionner:
car, selon les documents MDN :
Une troisième façon qui semble fonctionner (pas sûr que ce soit 100%) est d'utiliser
Object.getPrototypeOf
ce qui lève une exception si son argument n'est pas un objet:la source
obj === Object(obj)
renvoietrue
pour les tableaux.var x = []; console.log(x === Object(x)); // return true
getPrototypeOf
ne fonctionne pas, par exemple, avec les proxys révoqués, qui sont des objets mais des lancers.({}).toString.apply(obj) === '[object Object]'
cela ne fait- il pas la distinction entre les tableaux et les objets qui ne sont pas des tableauxunderscore.js fournit la méthode suivante pour savoir si quelque chose est vraiment un objet:
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):
la source
return obj === Object(obj) && Object.prototype.toString.call(obj) !== '[object Array]'
null
aussi. Doit être la réponse acceptée.Object.prototype.toString.call(myVar)
retournera:"[object Object]"
si myVar est un objet"[object Array]"
si myVar est un tableauPour plus d'informations à ce sujet et pourquoi c'est une bonne alternative à typeof, consultez cet article .
la source
typeof [] === 'object'
->true
. C'est ce dont vous avez besoin pour cette méthode.Object.prototype.toString.call(3)
->"[object Number]"
.Object.prototype.toString.call(new Number(3))
->"[object Number]
"getType=function(obj){return Object.prototype.toString.call(obj).match(/\[object (\w+)\]/)[1];};
Pour une simple vérification par rapport à Object ou Array sans appel de fonction supplémentaire (vitesse). Comme également affiché ici .
isArray ()
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.
la source
isObject
ne 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
Boolean(a)
est plus long, mais beaucoup plus intuitif. N'utilisez simplement pasnew Boolean(a)
: ( voici pourquoi )!{
caractère. Pour le cas du tableau, tant que vous n'avez pas besoin de prendre en charge IE <9, vous pouvez utiliserArray.isArray()
pour déterminer si quelque chose est un tableau. Il passe tous les cas de test que vous avez fournis.J'aime tout simplement:
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, reveneztrue
. Si l'une des trois conditions échoue, le&&
test sera court-circuité etfalse
sera renvoyé. Lenull
test peut être omis si vous le souhaitez (selon la façon dont vous l'utiliseznull
).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
la source
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'length
attribut 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é.length
propriété ni des méthodes commepush
,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.length
propriété (je voulais dire que les littéraux d'objet n'ont pas d'length
attribut 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 çaArray.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.typeof null
est"object"
, non"undefined"
.Avec fonction
Array.isArray
: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:
Quant à moi, c'est clair et simple, et ça marche! Voici mes tests:
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:
test simple:
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: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).
isObject
ne fonctionnera pas en cas deObject.create(null)
cause de l'implémentation interneObject.create
qui est expliquée ici mais vous pouvez l'utiliserisObject
dans une implémentation plus sophistiquée: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! 🙂
la source
isDate
pour votreDateObject dans le but d'écrire du code robuste sinon vous aurez uneisObject
méthode fragile .Date
dans mon commentaire a été mal choisie car oui, la réponse en discuteDate
. Mais ceDate
n'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)
retournefalse
. 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 .Oh mon Dieu! Je pense que cela pourrait être plus court que jamais, voyons ceci:
Code court et final
Expliqué
Types de retour
typeof JavaScript (y compris
null
) renvoie"object"
Vérifier leurs constructeurs
La vérification de leur
constructor
propriété renvoie la fonction avec leurs noms.Présentation de Function.name
Function.name
renvoie un nom en lecture seule d'une fonction ou"anonymous"
pour les fermetures.la source
Object.create(null)
et pourquoi vous le feriez quand même ...?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):
JavaScript pur:
ou
ou
ou
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:
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:
Angulaire:
Souligner et Lodash:
la source
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:
Il exclut les primitives (nombres simples /
NaN
/Infinity
, chaînes simples, symboles,true
/false
,undefined
etnull
) mais doit renvoyer true pour tout le reste (y comprisNumber
,Boolean
et lesString
objets). Notez que JS ne définit pas quels objets "hôte", tels quewindow
ouconsole
, doivent retourner lorsqu'ils sont utilisés avectypeof
, 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 avecObject.create(null)
, vous pouvez le faire:Edit 2018 : Parce que
Symbol.toStringTag
permet désormais de personnaliser la sortie deObject.prototype.toString.call(...)
, laisPlainObject
fonction ci-dessus peut revenirfalse
dans 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.la source
instanceof Object
, deux littéraux de fonction identiques ne sont pas strictement égaux, ils sont passés par référence, etc.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.
Cas 2.
Cas 3.
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.
la source
false
(comme souhaité) quandanyVar
est une fonction.La façon la plus raisonnable de vérifier le type d'une valeur semble être l'
typeof
opérateur. Le seul problème est qu'il est horriblement cassé:"object"
pournull
, qui appartient au type Null."function"
pour les objets appelables, qui appartiennent au type d'objet."unknown"
. Les seuls résultats interdits sont"function"
les types primitifs.typeof
n'est fiable que pour les nonnull
primitifs. Ainsi, un moyen de vérifier si une valeur est un objet serait de s'assurer que la chaîne retournée partypeof
ne correspond pas à une primitive, et que l'objet ne l'est pasnull
. 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 unListe complète mais non exhaustive des moyens appropriés pour tester si une valeur appartient au type d'objet.
Object
constructeurLe
Object
constructeur 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
===
: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
Object
n'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
try
déclarations n'existaient pas à l'époque.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
valeurLes anciennes spécifications ECMAScript exigeaient que la
this
valeur soit un objet. ECMAScript 3 introduitFunction.prototype.call
, qui permettait d'appeler une fonction avec unethis
valeur 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.
[[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.create
etObject.getPrototypeOf
nécessitent ECMAScript 5.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
try
instruction pour détecter les erreurs. Quelques exemples cachés, qui ne valent pas la peine d'être commentésAfficher l'extrait de code
Afficher l'extrait de code
Remarque: J'ai intentionnellement ignoré certaines approches comme
Object.getPrototypeOf(value)
(ES5) et lesReflect
méthodes (ES6) car elles appellent des méthodes internes essentielles qui pourraient faire des choses désagréables, par exemple sivalue
c'est un proxy. Pour des raisons de sécurité, mes exemples ne font référence quevalue
sans y accéder directement.la source
Essaye ça
la source
Object.prototype instanceof Object
-> faux.Object.create(null) instanceof Object
-> faux.new Date() instanceof Object
=> trueFonctions prêtes à l'emploi pour la vérification
Explication
En Javascript,
null
,Object
,Array
,Date
etfunction
s sont tous les objets. Bien,null
est un peu artificiel. Donc, il vaut mieux vérifier lenull
premier, pour détecter qu'il n'est pas nul.Vérification des
typeof o === 'object'
garanties quio
sont un objet. Sans cette vérification, celaObject.prototype.toString
n'aurait aucun sens, car il retournerait un objet pour tout, même pourundefined
etnull
! 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 sio
un objet, un objet dérivé commeArray
,Date
oufunction
.En
isDerivedObject
fonction, il vérifie sio
est 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() {})
retourneraitfalse
, mais maintenant il revienttrue
.On peut toujours changer la définition de ce qu'est un objet. Ainsi, on peut modifier ces fonctions en conséquence.
Les tests
la source
Si vous souhaitez vérifier si le
prototype
pourobject
provient uniquement deObject
. Filtres àString
,Number
,Array
,Arguments
, etc.Ou comme une fonction de flèche à expression unique (ES6 +)
la source
return Object.prototype.toString.call(n) === '[object Object]'
null
chèque, carObject.prototype.toString.call(null) === '[object Null]'
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'instanceof
opérateur. Il éliminera null, mais Array a un objet dans la chaîne d'héritage.La solution est donc:
la source
/./ instanceof Object //true
Un peu tard ... pour les "objets simples" (je veux dire, comme {'x': 5, 'y': 7}), j'ai ce petit extrait:
Il génère la sortie suivante:
Ç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. :)
la source
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.
la source
_.isObject
ce 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_.isPlainObject
me permet de faire.Cela fonctionnera. Il s'agit d'une fonction qui renvoie vrai, faux ou éventuellement nul.
la source
null
le résultat du test final plutôt quefalse
. Voir Quand dois-je apporter des modifications au code?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
Un objet n'est pas une primitive:
Ou bien:
Test pour n'importe quelle baie:
Test d'objet à l'exclusion de:
Date
RegExp
Boolean
Number
String
Function
tout tableaula source
Quand tout le reste échoue, j'utilise ceci:
la source
item.constructor === Object
?null
lève une exceptionUncaught TypeError: Cannot read property 'constructor' of null(…)
indexOf
ou à cause deconstructor.name
?La bibliothèque fonctionnelle Ramda a une fonction merveilleuse pour détecter les types JavaScript.
Paraphraser la fonction complète :
J'ai dû rire quand j'ai réalisé à quel point la solution était simple et belle.
Exemple d'utilisation de la documentation Ramda :
la source
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
,document
ou des objets avec des chaînes prototypes plus de 1 étape.Au lieu de vérifier la
typeof
variable 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 commetypeof
`` objet '.Après tout, l'
typeof
opé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 exempletypeof null === 'object'
). Vous trouverez ci-dessous une fonction qui détermine si la variablev
est un objet en répétant essentiellement deux vérifications:v
est'[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.
v
est remplacé par le prochain prototype de la chaîne avecv = Object.getPrototypeOf(v)
, mais aussi directement évalué après. Lorsque la nouvelle valeur dev
estnull
, 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.la source
la source
value
c'estnull
cela va jeter une erreur ...false
pour l'objetObject.assign({}, {constructor: null})
.Si vous souhaitez explicitement vérifier si la valeur donnée est
{}
.la source
!!obj
est un raccourci pour vérifier si elleobj
est véridique (pour filtrernull
)la source
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...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 pasnull
, n'est pas typeof'function'
, et est unObject
la source
true
pournew Date()
new Date()
Ce que j'aime utiliser c'est ceci
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
la source
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:
alors vous pouvez simplement faire:
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:
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:
de cette façon, vous pouvez faire comme le commentaire de inanc:
ou
la source
instanceof
pour rechercher des objets. Pourtant, ce n'est pas une science exacte.new Foo()
retourne unFoo
objet, comme celanew String()
retourne unString
objet, ounew Date()
retourne unDate
objet, vous pouvezFoo = function(){}; isVarTypeOf(new Foo(), Foo);
aussi faire