Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between Reflect.ownKeys(obj) and Object.keys(obj)?

Testing them out in a real simple case yields the same output:

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

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

When does Reflect.ownKeys(obj) produce output different from Object.keys(obj)?

like image 590
m0meni Avatar asked Dec 24 '15 07:12

m0meni


People also ask

What is the difference between object getOwnPropertyNames and object keys ()?

getOwnPropertyNames(a) returns all own properties of the object a . Object. keys(a) returns all enumerable own properties. It means that if you define your object properties without making some of them enumerable: false these two methods will give you the same result.

What is the difference between object key and object key in JavaScript?

key and object[key] accomplish the same thing. However, object. key only works if the key name is hardwired ( I mean not happening dynamically since it cannot change at run-time). It also does not work when the key is a number instead of a string.

What is the difference between object entries and object values?

The keys of an object is the list of property names. The values of an object is the list of property values. The entries of an object is the list of pairs of property names and corresponding values.

What is object in object keys?

The Object. keys() method returns an array of a given object's own enumerable property names, iterated in the same order that a normal loop would.


Video Answer


4 Answers

Object.keys() returns an array of strings, which are the object's own enumerable properties.

Reflect.ownKeys(obj) returns the equivalent of:

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

The Object.getOwnPropertyNames() method returns an array of all properties (enumerable or not) found directly upon a given object.

The Object.getOwnPropertySymbols() method returns an array of all symbol properties found directly upon a given object.

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));
like image 158
BatScream Avatar answered Oct 17 '22 15:10

BatScream


First, an example (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']

Here, Reflect.ownKeys() returns an array of the target object's own property keys. Namely, an array of all properties (enumerable or not) found directly upon the given object concatenated with an array of all symbol properties found directly upon the given object.

Object.keys() will only return the enumerable properties.

Enumerable properties are those that can be enumerated by a for...in loop, with the exception of properties inherited through the prototype chain. See the MDN description for more details.

Summary:

Reflect.ownKeys() is the equivalent of Object.getOwnPropertyNames(target).concat(Object.getOwnPropertySymbols(target)) which will return both enumerable and non-enumerable properties

whereas

Object.keys() returns enumerable properties but does not return non-enumerable properties (which is a characteristic of Object.getOwnPropertyNames()).

like image 33
Josh Durham Avatar answered Oct 17 '22 13:10

Josh Durham


  • Object.keys returns only enumerable string keys; Reflect.ownKeys returns both string and symbol keys regardless of their enumerability. Both operate on own properties only.
  • Object.keys returns an empty array if the argument is not an object and not null or undefined (e.g. Object.keys(1)), whereas Reflect.ownKeys throws a TypeError.
  • Reflect.ownKeys was introduced with ES6 and is not supported in older JavaScript engines.
like image 43
GOTO 0 Avatar answered Oct 17 '22 14:10

GOTO 0


In addition to what the other answers have already mentioned, Reflect.ownKeys is also guaranteed by the specification to return keys (and symbols) in the following order:

  • Integer numeric keys, in ascending order (0, 1, 2)
  • String keys, in the order they were inserted onto the object
  • Symbol keys

This order is required by the internal [[OwnPropertyKeys]] method which is invoked by Reflect.ownKeys.

In contrast, Object.keys calls EnumerableOwnPropertyNames, which requires:

  1. Order the elements of properties so they are in the same relative order as would be produced by the Iterator that would be returned if the EnumerateObjectProperties internal method were invoked with O.

Where EnumerateObjectProperties explicitly does not specify any order in which the properties are returned:

The mechanics and order of enumerating the properties is not specified

So, if you want to be absolutely certain that, while iterating over object properties, you iterate in insertion order for non-numeric keys, make sure to use Reflect.ownKeys (or Object.getOwnPropertyNames, which also invokes [[OwnPropertyKeys]]).

(All that said, while Object.keys, its variants, for..in loops, and JSON.stringify all officially iterate in an unspecified, implementation-dependant order, environments generally iterate in the same predictable order as Reflect.ownKeys anyway, luckily)

like image 35
CertainPerformance Avatar answered Oct 17 '22 15:10

CertainPerformance