Typeof en JavaScript est en fait très complexe. Il peut être utilisé pour faire beaucoup de choses, mais il a également de nombreux comportements étranges. Cet article répertorie ses multiples utilisations et souligne également les problèmes et solutions existants.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof?redirectlocale=en-US&redirectslug=JavaScript%2FReference%2FOperators%2Ftypeof
> type de non défini
'indéfini'
> typeof null // bug bien connu
'objet'
> type de vrai
'booléen'
> type de 123
'nombre'
> type de "abc"
'chaîne'
> type de fonction() {}
'fonction'
> type de {}
'objet'
> type de []
'objet'
> type de variable inconnue
'indéfini'
1. Vérifiez si une variable existe et a une valeur.
typeof renverra "indéfini" dans deux situations : lorsqu'une variable n'est pas déclarée et lorsque la valeur d'une variable n'est pas définie. Par exemple :
> typeof undeclaredVariable === "indéfini" true > var déclaréVariable > type de déclaréVariable 'indéfini' > typeof indéfini 'indéfini'
Il existe d'autres moyens de détecter si une valeur n'est pas définie :
> var valeur = non défini ; > valeur === non défini vrai
Mais si cette méthode est utilisée sur une variable non déclarée, une exception sera levée, car seul typeof peut détecter normalement les variables non déclarées sans signaler d'erreur :
> undeclaredVariable === non défini ReferenceError : undeclaredVariable n'est pas défini
Remarque : Les variables non initialisées, les paramètres formels sans paramètres passés et les propriétés inexistantes n'auront pas les problèmes ci-dessus, car ils sont toujours accessibles et la valeur est toujours indéfinie :
> var déclaréVariable; > déclaréVariable === non défini vrai > (function (x) { return x === non défini }()) vrai > ({}).foo === non défini vrai
Note du traducteur : Par conséquent, si vous souhaitez détecter l'existence d'une variable globale qui ne peut pas être déclarée, vous pouvez également utiliser if(window.maybeUndeclaredVariable){}
Problème : typeof est fastidieux pour accomplir une telle tâche.
Solution : Ce type d'opération n'est pas très courant, donc certaines personnes estiment qu'il n'est pas nécessaire de trouver une meilleure solution. Mais peut-être que quelqu'un proposera un opérateur spécial :
> défini undeclaredVariable faux > var déclaréVariable > défini déclaréVariable faux ;
Ou peut-être avons-nous également besoin d'un opérateur qui détecte si une variable est déclarée :
> déclaré undeclaredVariable faux > var déclaréVariable > déclaré déclaréVariable vrai
Note du traducteur : en Perl, l'opérateur défini ci-dessus est équivalent à défini () et l'opérateur déclaré ci-dessus est équivalent à existe ().
2. Déterminez si une valeur n'est pas égale à undefined ou null.
Problème : Si vous souhaitez vérifier si une valeur a été définie (la valeur n'est ni indéfinie ni nulle), alors vous rencontrez l'une des bizarreries les plus célèbres de typeof (considérée comme un bug) : typeof null renvoie "object":
> type d'objet nul
Note du traducteur : cela ne peut être considéré que comme un bug dans l'implémentation JavaScript d'origine, et c'est ainsi que la norme est désormais standardisée V8 une fois révisée et implémentée typeof null === "null", mais cela s'est finalement avéré irréalisable http : //wiki .ecmascript.org/doku.php?id=harmony:typeof_null
Solution : n'utilisez pas typeof pour cette tâche, utilisez plutôt une fonction comme celle-ci :
function isDefined(x) { return x !== null && x !== non défini }
Une autre possibilité consiste à introduire un "opérateur de valeur par défaut", où l'expression suivante renvoie defaultValue si myValue n'est pas défini :
maValeur ?? valeur par défaut
L'expression ci-dessus équivaut à :
(maValue !== non défini && maValue !== null) maValue : defaultValue ?
Ou:
maValeur ??= valeur par défaut
En fait, il s’agit d’une simplification de l’énoncé suivant :
maValeur = maValeur ??
Lorsque vous accédez à une propriété imbriquée, telle qu'un bar, vous aurez peut-être besoin de l'aide de cet opérateur :
obj.foo.bar
Si obj ou obj.foo n'est pas défini, l'expression ci-dessus lèvera une exception. Un opérateur.?? permet à l'expression ci-dessus de renvoyer la première valeur rencontrée lors du parcours des propriétés couche par couche. Propriétés non définies ou nulles :
obj.??foo.??bar
L'expression ci-dessus équivaut à :
(obj === non défini || obj === null) ? obj : (obj.foo === non défini || obj.foo === null) ?
3. Distinguer les valeurs d'objet et les valeurs primitives
La fonction suivante teste si x est une valeur d'objet :
function isObject(x) { return (typeof x === "function" || (typeof x === "object" && x !== null) }
Problème : la détection ci-dessus est compliquée car typeof considère les fonctions et les objets comme des types différents, et typeof null renvoie "object".
Solution : La méthode suivante est également souvent utilisée pour détecter les valeurs d'objet :
function isObject2(x) { return x === Objet(x);
Attention : vous pensez peut-être que vous pouvez utiliser instanceof Object pour détecter ici, mais instanceof détermine la relation d'instance en utilisant le prototype d'un objet, alors qu'en est-il des objets sans prototype :
> var obj = Objet.create(null); > Objet.getPrototypeOf(obj) null
obj est bien un objet, mais ce n'est une instance d'aucune valeur :
> type d'objet obj 'objet' > obj instanceof Objet faux
Dans la pratique, on rencontre rarement un tel objet, mais il existe et a son utilité.
Note du traducteur : Object.prototype est un objet qui existe par défaut et n'a pas de prototype.
>Object.getPrototypeOf(Object.prototype)null>typeof Object.prototype'object'>Object.prototype instanceof Object false
4.Quel est le type de valeur primitive ?
typeof est le meilleur moyen de vérifier le type d'une valeur primitive.
> type de "abc" 'chaîne' > type de non défini 'non défini'
Problème : vous devez être conscient du comportement étrange de typeof null.
> typeof null // Soyez prudent !
Solution : La fonction suivante peut résoudre ce problème (uniquement pour ce cas d'utilisation).
function getPrimitiveTypeName(x) { var typeName = typeof x; switch(typeName) { case "undefined": case "boolean": case "number": case "string": return typeName "object": if (x == = null) { return "null"; } default: // Aucun des jugements précédents passés ne lance new TypeError("Le paramètre n'est pas une valeur primitive : "+x } }
Une meilleure solution : implémenter une fonction getTypeName(), qui en plus de renvoyer le type de la valeur d'origine, peut également renvoyer l'attribut interne [[Class]] de la valeur de l'objet. Voici comment implémenter cette fonction (Note du traducteur : jQuery $.type est une telle implémentation)
5. Si une certaine valeur est une fonction
typeof peut être utilisé pour détecter si une valeur est une fonction. > typeof function () {} 'function' > typeof Object.prototype.toString 'function'
En principe, instanceof La fonction peut également détecter cette exigence. À première vue, il semble que la méthode d'écriture soit plus élégante. Cependant, le navigateur a une bizarrerie : chaque cadre et fenêtre a ses propres variables globales. Par conséquent, si vous mettez un certain cadre dans If. l'objet est passé à un autre framework, instanceof ne fonctionnera pas correctement car les deux frameworks ont des constructeurs différents. C'est pourquoi il existe une méthode Array.isArray() dans ECMAScript 5. Ce serait bien s'il existait une méthode multi-framework pour vérifier si un objet est une instance d'un constructeur donné. La méthode getTypeName() ci-dessus est une solution de contournement disponible. , mais il existe peut-être une solution plus fondamentale.
6.Aperçu
Les fonctionnalités mentionnées ci-dessous devraient être les fonctionnalités les plus urgentes de JavaScript à l'heure actuelle et peuvent remplacer certaines des fonctionnalités fonctionnelles des responsabilités actuelles de typeof :
isDefined() (comme Object.isDefined()) : peut être utilisé comme fonction ou opérateur
estObjet()
getTypeName()
Un mécanisme inter-framework pour détecter si un objet est une instance d'un constructeur spécifié
La nécessité de vérifier si une variable a été déclarée peut ne pas nécessiter son propre opérateur.