1

This is my Array

let setOne = [""];

Now, I created a function that takes the element from the array i.e setOne, store that element in one Object as a property name and give that property-name a value of true and prints the object data.

Function is

function checkTheSameBetter(setOne) {
  let ObjectShop = {};
  for (let indexSetOne = 0; indexSetOne < setOne.length; indexSetOne++) {
    ObjectShop[setOne[indexSetOne]] = true;
  }
  console.log(ObjectShop);
}

The Output which I get is

{ '': true }

No Problem so far

Here comes the main part when I add another value to an array i.e setOne, consider "1".

let setOne = ["",1];

And then when I execute the function checkTheSameBetter. I get output

 {'1': true, '': true }

So my question is, "how did that '1' get stored in the first position?"

The output I expected was in this order

{'': true, '1': true}

Here is the sandbox Link https://codesandbox.io/s/cranky-cori-qx116?file=/src/index.js

can anyone please tell me what's happening here? If you need any clarification I will give it.

Thank You

Darshan
  • 56
  • 9
  • 3
    If you want something like an object that preserves order of keys, consider [`Map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map). – Niet the Dark Absol Aug 09 '20 at 15:14
  • objects have key and value. why it stores order ? I think it is normal behavior try with some different value and see yourself . the key and value won't jiggle up –  Aug 09 '20 at 15:15

2 Answers2

2

JS Objects have traditionally been 'unordered' (until ES5). Since ES6, there is a predictable order to the Object properties iteration. It, however, isn't the 'insertion' order. The order of keys will be as follows:

  1. First, all non-negative integer keys less than 232, in ascending order. (eg. '1', '79', etc. basically all valid array indices. Caveat: '05' wouldn't be considered integer key, since the integer parsed from it will yield a different string representation).
  2. Then, all String keys, in the original order of insertion. (Numeric strings not falling within bounds of step one will be considered here.)
  3. Then, all Symbol keys, in the original order of insertion.

Looking at the rules above, it makes sense that '1', being an integer key, appeared before '' (a string).

Please note that this only applies to ES2015 and later. To avoid confusion, and eye rolls from colleagues habituated of viewing objects as unordered, please don't rely on enumeration order of Object properties. If the enumeration order is relevant, you can always use Map which guarantees that insertion order will be maintained.

d_shiv
  • 1,670
  • 10
  • 8
  • 1
    Nit-picking: both answers have a similar issue, i'll just comment on one: it's "array-index", integers from 0 to 2**32 - 2. A related question/answer-pair can be found [here](https://stackoverflow.com/questions/60121521/object-keys-order-for-large-numerical-indexes) – ASDFGerte Aug 09 '20 at 15:37
  • @ASDFGerte _both answers have a similar issue_ - i don't think it is an _issue_. Describing array index properties as non-negative numeric keys is fine in my opinion. – Yousaf Aug 09 '20 at 15:52
  • @ASDFGerte, agreed. I didn't explicitly mention the bounds for integer. Will update my answer. – d_shiv Aug 09 '20 at 16:02
1

ES6 defines an order in which own properties of an object are enumerated. Following are the rules according to which own properties of an object are enumerated:

  • String properties whose names are non-negative numbers are listed first, from smallest to largest. This means that properties of array and array-like objects will be enumerated in order.

  • After that, all properties with string names are listed in the order they were added in the object. This also includes properties that look like non-negative numbers or floating point numbers.

  • At last, properties whose names are Symbols are listed in the order they were added in the object.

Following functions list the properties in the above described order, subject to their own constraints.

  • Object.keys()
  • Object.getOwnPropertyNames()
  • Object.getOwnPropertySymbols()
  • Reflect.ownKeys()

One thing to keep in mind is that enumeration order for for in loop is not as tightly specified as it is for above mentioned enumeration functions but it typically enumerates own properties in the order described above.

As for in loop also enumerates properties in the prototype chain, once own properties have been enumerated, it will then move up the prototype chain, enumerating properties of each prototype object in the same order as described above. Although if a property has already been enumerated, any property with the same name won't be enumerated again. Property won't be enumerated even if a non-enumerable property with the same name has already been considered.

const obj = {};

obj[2] = 2;
obj['-1'] = -1;
obj['1'] = 1;
obj['as'] = 'as';
obj['10'] = 10;
obj['b'] = 'b';

console.log(Reflect.ownKeys(obj));
console.log(Object.getOwnPropertyNames(obj));

for (const key in obj) {
  console.log(key);
}
.as-console-wrapper { max-height: 100% !important; top: 0; }
Yousaf
  • 27,861
  • 6
  • 44
  • 69