user3025289
user3025289

Reputation:

How can I obtain Symbol names (literals)?

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

Answers (3)

Neall
Neall

Reputation: 27114

The reason you're having problems is that Javascript symbols don't have "names", exactly.

symbols don't really have names

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.

symbols do have descriptions

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)

conclusion

  • A variable has a name.
  • A variable will point to a value.
  • A symbol is a kind of value.
  • But a value does not point back at any of the variables that contain it.
  • So you can't get a variable name from a value.
  • But if you want something useful to look at when you're debugging, give your symbols descriptions.

Upvotes: 10

Daniel Wolf
Daniel Wolf

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

Pointy
Pointy

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

Related Questions