Search code examples
javascriptsymbols

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

Solution

  • 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.