Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"for ... in" loop JavaScript - does it include Symbol properties

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]);
}
like image 934
peter.petrov Avatar asked Dec 21 '19 12:12

peter.petrov


2 Answers

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");
like image 131
T.J. Crowder Avatar answered Oct 12 '22 06:10

T.J. Crowder


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]);
}
like image 1
Anonymous Avatar answered Oct 12 '22 05:10

Anonymous