Reputation:
Following situation:
var myVehicle = { brand: 'Tesla' };
var isMoving = Symbol();
var currentStatus = Symbol();
myVehicle[isMoving] = true;
myVehicle[currentStatus] = 'moving';
I want to print the names of used "Symbol-properties" in my object myVehicle
console.log(
myVehicle[isMoving], // true
myVehicle[currentStatus], // 'moving',
Reflect.ownKeys(myVehicle), // [ 'brand', Symbol(), Symbol() ]
Object.getOwnPropertySymbols(myVehicle), // [ Symbol(), Symbol() ]
);
How can I get the names like:
[isMoving, currentStatus]
instead of [ Symbol(), Symbol() ]
Solution
No names, but descriptions:
var myVehicle = { brand: 'Tesla' };
var isMoving = Symbol('isMoving');
var currentStatus = Symbol('currentStatus');
myVehicle[isMoving] = true;
myVehicle[currentStatus] = 'moving';
Object.getOwnPropertySymbols(myVehicle).forEach((sym, index) =>
console.log(
index + 1 + '. Symbol Description: ',
sym.description + ': ',
myVehicle[sym],
),
);
Outputs:
1. Symbol Description: isMoving: true
2. Symbol Description: currentStatus: moving
Upvotes: 7
Views: 4258
Reputation: 27114
The reason you're having problems is that Javascript symbols don't have "names", exactly.
When you assign a symbol to a variable, that does not give the symbol a name that follows it around. For instance, consider this code:
function getMeASymbol() {
var alpha = Symbol()
var beta = alpha
return beta
}
var gamma = getMeASymbol()
Inside the function we create a symbol and store it in alpha
.
Then we store the same symbol in beta
.
Finally, we return the symbol and the caller stores it in gamma
.
None of those three variable names is really attached to the symbol.
What's more, alpha
and beta
don't even exist by the time gamma
is assigned.
If you pass in a description when you create a symbol, it keeps that string around for information purposes.
You might consider that the symbol's "name", although those "names" aren't necessarily unique.
Later, you can see the description inside the return value of the symbol's .toString()
method.
console.log(Symbol('mySymbol').toString()) // prints "Symbol(mySymbol)"
If you want to get just the original description, you can strip off the extra stuff:
console.log(Symbol('mySymbol').toString().slice(7,-1))
update Symbols now have a .description
property you can use instead of calling toString
and stripping off the extra characters.
console.log(Symbol('mySymbol').description)
Upvotes: 10
Reputation: 13643
As mentioned by @Pointy and @Neall, symbols don't have names, but they can have descriptions.
Here's how you create a symbol with a description:
const isMoving = Symbol('isMoving');
And here's how you access this description:
console.log(isMoving.description); // Prints "isMoving"
The property description
isn't part of the official EcmaScript standard yet. As of this writing, it is in Stage 3. So not every environment supports it. For details, see the MDN article.
Note that a symbol's description has nothing to do with the name of the variable holding it. Consider the following:
const symbol1 = Symbol('Hello world!');
console.log(symbol1.description); // Prints "Hello world!", *not* "symbol1"
const symbol2 = symbol1;
console.log(symbol2.description); // Also prints "Hello world!"
Upvotes: 1
Reputation: 413720
The question doesn't really make sense. Those variable names have nothing really to do with the Symbol instances they reference. When you construct the Symbol, you can give it a string to be used as a description:
var isMoving = Symbol("isMoving");
When you console.log()
such a Symbol, you'll see
Symbol(isMoving)
You can use .toString()
to get the description, so if you wanted the description strings from all the Symbol properties:
var descrs = Object.getOwnPropertySymbols(obj).map(s => s.toString());
Upvotes: 4