I did a bit of work on the Mozilla Development Network (MDN).
It turns out that objects have an obj.propertyIsEnumerable(prop) method to check if a property is enumerated. Of the examples shown in MDN, properties inherited through the prototype chain are not enumerable, so the method returns false for these properties.
Examples of non-enumerable properties are the constructors and the length property of arrays.
For the recurring part of the question, I will cite MDN: "Iterable in ECMAScript 6 is an interface (or, in other words, a protocol), and not a type of object, such as Array or Map."
That is, an object must implement this interface in order to make its properties iterable. This applies to built-in iterations such as String, Array, Map, Set, WeakSet, and Generator objects.
The following code illustrates this:
var aString = "hello" typeof aString[Symbol.iterator] // "function" aString[Symbol.iterator]() + "" // "[object String Iterator]" [...aString] // ["h", "e", "l", "l", "o"]
Of course, you can define your own iterator implementation.
Returning to the question, properties bound to an object or its prototype (directly, and not through inheritance) will be displayed as enumerated in a for...in loop. For iterations, you need an implementation, both mentioned earlier, and yours. Here is a great example from MDN.
let arr = [ 3, 5, 7 ]; arr.foo = "hello"; for (let i in arr) { console.log(i); // logs "0", "1", "2", "foo" these are property names or indexes } for (let i of arr) { console.log(i); // logs "3", "5", "7" these are actual values of an // iterable implementation provided by the array prototype }
The let keyword in this context is equivalent to the definition of var (although it has more consequences, it is beyond the scope of this post).
As you can see, the array already has an implementation of the iterable interface (from the prototype of the array), so it gives its values ββwhen using the for...of loop, while the foo property is not displayed (neither the value or the name of the property).
So, if your object does not implement the iterable interface, it should not be iterable (in principle) and, thus, displays its properties in a for...of loop.