web-dev-qa-db-fra.com

Quelle est la différence entre Reflect.ownKeys (obj) et Object.keys (obj)?

Les tester dans un cas simple et réel donne le même résultat:

const obj = {a: 5, b: 5};
console.log(Reflect.ownKeys(obj));
console.log(Object.keys(obj));

// Result
['a', 'b']
['a', 'b']

Quand Reflect.ownKeys(obj) produit-elle une sortie différente de Object.keys(obj)?

44
m0meni

Object.keys() renvoie un array de chaînes, qui sont les propres propriétés de l'objet enumerable.

Reflect.ownKeys(obj) renvoie l'équivalent de:

Object.getOwnPropertyNames(target).
                   concat(Object.getOwnPropertySymbols(target))

La méthode Object.getOwnPropertyNames() renvoie un tableau de toutes les propriétés ( enumerable ou non ) trouvé directement sur un objet donné.

La méthode Object.getOwnPropertySymbols() renvoie un tableau de toutes les propriétés symbol trouvées directement sur un objet donné.

var testObject;
Object.defineProperty(testObject, 'myMethod', {
    value: function () {
        alert("Non enumerable property");
    },
    enumerable: false
});

//does not print myMethod since it is defined to be non-enumerable
console.log(Object.keys(testObject));   

//prints myMethod irrespective of it being enumerable or not.
console.log(Reflect.ownKeys(testObject)); 

Un petit fiddle pour démontrer.

44
BatScream

Tout d'abord, un exemple ( ES6Fiddle ):

// getFoo is property which isn't enumerable
var my_obj = Object.create({}, { getFoo: { value: function() { return this.foo; } } });
my_obj.foo = 1;

console.log(Object.keys(my_obj)); // console ['foo']
console.log(Reflect.ownKeys(my_obj)); // console ['getFoo', 'foo']

Ici, Reflect.ownKeys() renvoie un tableau des propres clés de propriété de l'objet cible. A savoir, un tableau de toutes les propriétés (énumérables ou non) trouvées directement sur l'objet donné concaténées avec un tableau de toutes les propriétés symbol trouvées directement sur l'objet donné.

Object.ownKeys() ne renverra que les propriétés énumérables.

Les propriétés énumérables sont celles qui peuvent être énumérées par un for ... in loop , à l'exception des propriétés héritées de la chaîne de prototypes. Voir la description MDN pour plus de détails.

Résumé:

Reflect.ownKeys () est l'équivalent de Object.getOwnPropertyNames(target).concat(Object.getOwnPropertySymbols(target)) qui renverra les propriétés énumérables et non énumérables

tandis que

Object.keys () renvoie des propriétés énumérables mais ne renvoie pas de propriétés non énumérables (ce qui est une caractéristique de Object.getOwnPropertyNames () ).

12
Josh Durham
  • Object.keys Renvoie uniquement les clés de chaîne énumérables; Reflect.ownKeys Renvoie les clés de chaîne et de symbole quelle que soit leur énumérabilité. Les deux fonctionnent uniquement sur leurs propres propriétés.
  • Object.keys Renvoie un tableau vide si l'argument n'est pas un objet et non null ou undefined (par exemple Object.keys(1)), alors que Reflect.ownKeys jette un TypeError.
  • Reflect.ownKeys A été introduit avec ES6 et n'est pas pris en charge dans les anciens moteurs JavaScript.
5
GOTO 0

En plus de ce que les autres réponses ont déjà mentionné, Reflect.ownKeys est également garanti par la spécification pour renvoyer les clés (et symboles) dans l'ordre suivant:

  • Touches numériques entières, dans l'ordre croissant (0, 1, 2)
  • Clés de chaîne, dans l'ordre où elles ont été insérées dans l'objet
  • Touches de symbole

Cette commande est requise par le service interne [[OwnPropertyKeys]] méthode invoquée par Reflect.ownKeys .

En revanche, Object.keys appelle EnumerableOwnPropertyNames , ce qui nécessite:

  1. Ordonnez les éléments de properties pour qu'ils soient dans le même ordre relatif que celui produit par l'itérateur qui serait retourné si la méthode interne EnumerateObjectProperties était invoquée avec O.

EnumerateObjectProperties explicitement ne spécifie aucun ordre dans lequel les propriétés sont retournées:

La mécanique et l'ordre d'énumération des propriétés ne sont pas spécifiés

Donc, si vous voulez être absolument certain que, tout en itérant sur les propriétés des objets, vous itérez dans l'ordre d'insertion des clés non numériques, assurez-vous d'utiliser Reflect.ownKeys (ou Object.getOwnPropertyNames , qui invoque également [[OwnPropertyKeys]]).

(Tout cela dit, tandis que Object.keys, ses variantes, for..in boucles et JSON.stringify tous itèrent officiellement dans un ordre non spécifié, dépendant de l'implémentation, les environnements itèrent généralement dans le même ordre prévisible que Reflect.ownKeys de toute façon, heureusement)

1
CertainPerformance