6

MDN says that

A for...in loop only iterates over enumerable, non-Symbol properties.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in

But I did a simple test and it shows that even Symbol properties are iterated in a "for...in" loop.

What is the catch here?
What am I missing?

Example 1:

var symbol = Symbol("test");

function Animal(name){
    this.name = name;
}

Animal.prototype = {};
Animal.prototype.constructor = Animal;

function Dog(breed){
    this.breed = breed;
    this.name = "Dog";
    this.s = symbol;
}

Dog.prototype = new Animal();
Dog.prototype.constructor = Dog;

console.log("001");
var d = new Dog("Sharo");
for (let x in d){
    console.log(x, ":", d[x]);
}

console.log("002");
d = new Object();
for (let x in d){
    console.log(x, ":", d[x]);
}

console.log("003");
d = new Number(5);
for (let x in d){
    console.log(x, ":", d[x]);
}

3
  • 2
    Can you show the code of the test? Commented Dec 21, 2019 at 12:59
  • @funnydman Yes, sure. Code added. Commented Dec 21, 2019 at 12:59
  • Note to future readers: I've edited the MDN article to clarify the sentence that caused this question. Commented Dec 21, 2019 at 13:12

2 Answers 2

5

for-in ignores Symbol-keyed properties, not properties keyed by strings whose value is a Symbol. for-in doesn't pay any attention to the value of the properties at all.

So for instance, this for-in loop never executes its body:

const obj = {
    [Symbol("x")]: "foo"
};
for (const name in obj) {
    console.log(`name = ${String(name)}`); // never runs
}
console.log("End of script");

But this one does, because the property's key is a string, it's just that its value is a Symbol:

const obj = {
    foo: Symbol("x")
};
for (const name in obj) {
    console.log(`name = ${name}`);
}
console.log("End of script");

Sign up to request clarification or add additional context in comments.

5 Comments

Hm... I understood "non-Symbol properties" as "properties which are not Symbols". Seems natural to me. OK, I think I get it now.
@peter.petrov - It's just slightly sloppy wording on MDN (which is community-edited). It should be "A for...in loop only iterates over enumerable properties keyed by strings (ignoring ones keyed by Symbols)" or similar.
Sorry... actually... wait a min... aren't properties always keyed by strings? (1) I got confused now... This is sending me back to the "A-B-C" :) ... If the answer to (1) is "NO", then... (2) what values/things can be keys for an object's properties? Seems that only strings and symbols and then... in that respect symbols are very special, since only symbols and strings can be keys for an object's properties. Or... am I deluded again?
Never mind... I posted that as a separate question, and now all my confusions are cleared, I think :) stackoverflow.com/questions/59436684/…
@peter.petrov - I was away from my desk. :-) I've answered now.
2

A for...in loop only iterates over enumerable, non-Symbol properties.

This is talking about the properties, which are the keys of objects, not the values. The Symbol property won't show in this example:

var symbol = Symbol("test");

function Animal(name){
    this.name = name;
}

Animal.prototype = {};
Animal.prototype.constructor = Animal;

function Dog(breed){
    this.breed = breed;
    this.name = "Dog";
    this[symbol] = symbol;
}

Dog.prototype = new Animal();
Dog.prototype.constructor = Dog;

console.log("001");
var d = new Dog("Sharo");
for (let x in d){
    console.log(x, ":", d[x]);
}

console.log("002");
d = new Object();
for (let x in d){
    console.log(x, ":", d[x]);
}

console.log("003");
d = new Number(5);
for (let x in d){
    console.log(x, ":", d[x]);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.