In ES6 properties can be defined as symbol properties:
var symbol = Symbol();
var object = {};
object[symbol] = 'value';
MDN defines enumerable properties as 'those which can be iterated by a for..in loop' (1). Symbol properties are never iterated by a for...in loop, therefore they can be considered non-enumerable (2).
Does it make any sense, then, that you can do this:
Object.defineProperty(object, symbol, {
value: 'value',
enumerable: true
});
and that querying object for it's descriptor does indeed confirm that this property is enumerable:
Object.getOwnPropertyDescriptor(object, symbol)
// -> { enumerable: true }
Why? What use is this?
(1) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Enumerability_and_ownership_of_properties
(2) for...in uses [[Enumerate]]
, which only includes string keys. Probably the definition on MDN should be changed now that we have symbol properties.
MDN defines enumerable properties as 'those which can be iterated by a for..in loop' (1). Symbol properties are never iterated by a for...in loop, therefore they can be considered non-enumerable (2).
Enumerable properties are those properties whose internal enumerable flag is set to true, which is the default for properties created via simple assignment or via a property initializer. Properties defined via Object.
Syntax: Object. defineProperty(obj, prop, descriptor)
Symbols are new primitive type introduced in ES6. Symbols are completely unique identifiers. Just like their primitive counterparts (Number, String, Boolean), they can be created using the factory function Symbol() which returns a Symbol. Every time you call the factory function, a new and unique symbol is created.
Yes, there's a reason for allowing Symbol
properties to be enumerable: Object.assign
:
let s1 = Symbol();
let s2 = Symbol();
let s3 = Symbol();
let original = {};
original[s1] = "value1"; // Enumerable
Object.defineProperty(original, s2, { // Enumerable
enumerable: true,
value: "value2"
});
Object.defineProperty(original, s3, { // Non-enumerable
value: "value3"
});
let copy = {};
Object.assign(copy, original);
console.log("copy[s1] is " + copy[s1]); // value1, because it was enumerable
console.log("copy[s2] is " + copy[s2]); // value2, because it was enumerable
console.log("copy[s3] is " + copy[s3]); // undefined, because it wasn't enumerable
Live Copy on Babel's REPL.
Just for clarity:
MDN defines enumerable properties as 'those which can be iterated by a for..in loop' (1).
That's simply wrong for ES6 (ES2015). It was a reasonable, if simplistic, definition in ES5 and earlier, no it's no longer even simplistically correct because of Symbol
s. I've fixed the article.
This is a CW because it was the outgrowth of the comments on the question.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With