68 votes

Détection d'objet JavaScript: syntaxe à points et mot-clé 'in'

J'ai vu les deux manières de détecter si un UA met en œuvre un spécifique JS propriété: if(object.property) et if('property' in object).

J'aimerais entendre les opinions sur ce qui est mieux, et plus important encore, pourquoi. Est sans équivoque un meilleur que l'autre? Il n'y a plus que ces deux façons de faire de propriété de l'objet de la détection? Veuillez couvercle de prise en charge du navigateur, les pièges, la vitesse d'exécution, et telles, plutôt que sur l'esthétique.

Edit: les Lecteurs sont encouragés à exécuter les tests à jsperf.com/object-detection

122voto

pimvdb Points 66332
  • if(object.property)

    va échouer dans les cas, il n'est pas défini (qui est ce que vous voulez), et dans les cas elle a été fixée à une valeur fausse, par exemple, undefined, null, 0 etc (ce qui n'est pas ce que vous voulez).

    var object = {property: 0};
    if(object.property) { ... } // will not run
    
  • if('property' in object)

    est un peu mieux, car il sera fait retour si l'objet a vraiment du bien, ne cherche pas à sa valeur.

    var object = {property: 0};
    if('property' in object) { ... } // will run
    if('toString' in object) { ... } // will also run; from prototype
    
  • if(object.hasOwnProperty('property'))

    c'est encore mieux, car il vous permettra de distinguer entre les propriétés de l'occurrence et les propriétés du prototype.

    var object = {property: 0};
    if(object.hasOwnProperty('property')) { ... } // will run
    if(object.hasOwnProperty('toString')) { ... } // will not run
    

Je dirais que la performance n'est pas que les grandes d'un problème ici, sauf si vous êtes à la vérification des milliers de fois par seconde, mais dans ce cas, vous devriez envisager une autre structure du code. L'ensemble de ces fonctions/syntaxes sont pris en charge par les navigateurs récents, hasOwnProperty a été autour pendant un long moment, trop.


Edit: Vous pouvez également effectuer une fonction pour vérifier l'existence d'une propriété en passant n'importe quoi (même des choses qui ne sont pas des objets) comme un objet, comme ceci:

function has(obj, prop) {
    return Object.prototype.hasOwnProperty.call(obj, prop);
}

Maintenant cela fonctionne:

has(window, 'setTimeout'); // true

même si window.hasOwnProperty === undefined (ce qui est le cas dans la version de IE 8 ou inférieur).

10voto

Tim Down Points 124501

Ça dépend vraiment de ce que vous voulez atteindre. Tu parles d'accueil des objets ( window et les nœuds DOM)? Si donc, le plus sûr de vérifier est - typeof, ce qui fonctionne pour tous les objets hôte je connais:

 if (typeof object.property != "undefined") { ... }

Notes:

  • Évitez object.hasOwnProperty() pour les objets hôte, en raison de l'hôte objets ne sont pas obligés d'hériter d' Object.prototype et, par conséquent, ne peuvent pas avoir un hasOwnProperty() méthode (et d'ailleurs dans IE < 9, généralement, ils ne sont pas).
  • Une simple contrainte de type Boolean (par exemple, if (object.property) { ... }) est un mauvais test de l'existence d'une propriété, car il va donner de faux négatifs pour falsy valeurs. Par exemple, pour un vide textarea, if (textarea.selectionStart) { ... } ne va pas exécuter le bloc, même si la propriété existe. Aussi, certains d'accueil des propriétés de l'objet renvoie une erreur dans les anciennes versions d'IE lors de la tentative de forcer une valeur Booléenne (par exemple, var xhr = new ActiveXObject("Microsoft.XMLHTTP"); if (xhr.responseXML) { ... }).
  • L' in de l'opérateur est un meilleur test de l'existence d'une propriété, mais il y a encore une fois pas de garanties sur la prise en charge dans objets hôte.
  • Je recommande la prise en considération de la performance pour ce genre de tâche. Choisissez l'option la plus sûre pour votre projet et optimiser plus tard. Il y aura presque certainement beaucoup mieux de candidats pour l'optimisation de la propriété existence de contrôles.

Pour plus d'information sur ce, je vous recommande cet excellent article de Pierre Michaux.

2voto

Ben Lee Points 25935

Définitivement if ('property' in object) est la bonne façon de faire. Qui fait des tests, si le bien est dans l'objet (ou dans sa chaîne de prototype, de plus en plus sur ce ci-dessous).

if (object.property) sur l'autre main, va contraindre des "biens" en vérité/flase valeur. Si la propriété n'est pas définie, il retourne "undefined", qui sera contraint de faux, et semblent fonctionner. Mais ce ne sera pas suffisante pour un certain nombre d'autres valeurs de propriétés. javascript est notoirement incompatibles dans ce qu'il considère comme truthy et falsy.

Enfin, comme je l'ai dit ci-dessus, 'property' in 'object' retournera true si elle est dans le n'importe où dans la chaîne de prototype. Si vous voulez tester c'est sur l'objet lui-même, et pas quelque part plus haut dans la chaîne, vous devez utiliser l' hasOwnProperty méthode comme suit:

if (object.hasOwnProperty('property')) ...

0voto

Alxandr Points 5413

Le premier échouera si "propriété" vaut 0. Pour vous assurer qu'il existe bien une propriété, vous devez vérifier que object.property !== undefined ou utiliser le mot-clé in.

[Modifier]

Il y a aussi la fonction hasOwnProperty, mais je ne l'ai jamais vraiment utilisée et je ne peux donc pas en dire beaucoup. Bien que je pense que cela ne retournera pas vrai si la propriété est définie dans un prototype, ce que vous voulez parfois, d'autres fois, vous ne voulez pas.

0voto

Fordi Points 917

Cela vous permet d'utiliser window.hasOwnProperty comme référence à lui-même ou à quelque chose d'autre, quel que soit votre hôte de script.

 // No enclosing functions here
if (!('hasOwnProperty' in this))
    function hasOwnProperty(obj, prop) {
        var method = Object.prototype.hasOwnProperty;
        if (prop === undefined)
            return method.call(this, obj);
        return method.call(obj, prop);
    }

//Example of use
var global = global || this; //environment-agnostic way to get the global object
var x = 'blah';
WScript.Echo(global.hasOwnProperty('x') ? 'true' : 'false'); //true

//Use as non-object method
var y = { z: false };
WScript.Echo(hasOwnProperty(y, 'z') ? 'true' : 'false'); //true
WScript.Echo(hasOwnProperty(y, 'w') ? 'true' : 'false'); //false

// true ಠ_ಠ
WScript.Echo(hasOwnProperty(global, 'hasOwnProperty') ? 'true' : 'false');
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X