7

I try to create object with Symbol key and find corresponding value with Symbol.for, but it doesn't work:

const sym = Symbol("x");

let obj = {
  [sym]: "val"
}

console.log(obj[sym]); // "val"
console.log(obj[Symbol.for("x")]); // undefined, but expected "val"

Why?

mqklin
  • 1,928
  • 5
  • 21
  • 39
  • possible duplicate of [Symbol.for(string) in ECMAScript 6](http://stackoverflow.com/q/30984858/1048572). Notice also that `Symbol("x") !== Symbol("x")` – Bergi Feb 22 '16 at 21:27

2 Answers2

13

Symbols created using Symbol() are unique and immutable, so the only way you can reference it is by assigning it to a variable.

It's important to note that the constructor param is actually a description of the symbol, not a key. From MDN:

A description of the symbol which can be used for debugging but not to access the symbol itself

(emphasis mine)

Symbol.for on the other hand stores Symbols in a global registry list using the specified key, so for your example to work you need to both create and access the symbol using Symbol.for:

const sym = Symbol.for("x"); // Create a symbol in the global registry

let obj = {
  [sym]: "val"
}

console.log(obj[Symbol.for("x")]); // Access the symbol from the global registry
CodingIntrigue
  • 75,930
  • 30
  • 170
  • 176
  • 4
    From the [MDN page](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/for): _“**In contrast to `Symbol()`, the `Symbol.for()` function creates a symbol available in a global symbol registry list.** `Symbol.for()` does also not necessarily create a new symbol on every call, but checks first if a symbol with the given key is already present in the registry.”_ So `Symbol()` doesn’t add a symbol to any global registry, only `Symbol.for()` does. (Just as a clarification.) – Sebastian Simon Jan 04 '16 at 09:32
  • 1
    @Xufox Thanks, that's a good clarification as I couldn't quite get my terminology for `Symbol()` across the way I wanted – CodingIntrigue Jan 04 '16 at 09:36
  • 1
    So `Symbol("x")` and `Symbol.for("x")` absolutely different symbols? – mqklin Jan 04 '16 at 09:39
  • 1
    Yes. They are always different symbols. – CodingIntrigue Jan 04 '16 at 09:43
  • @RGraham @Xufox, thus `Symbol.for` is not so *isolate*? For example, if I will use `Symbol.for("very-unique")`, and another developer library will use the same, there will be incorrect behavior? If it's true, what are the benefits from it? Why not just a property with `["very-unique"]` name? – mqklin Jan 12 '16 at 04:40
  • @mqklin Correct that it's not isolated, but take for example `var obj = { "very-unique": false };` - that key name could be overwritten by anyone using the key `very-unique`. However, using `var obj = { [Symbol.for("very-unique")]: true };` you can be guaranteed the key can only be accessed or overwritten by the value for that Symbol. – CodingIntrigue Jan 12 '16 at 08:08
4

That is not how Symbol.for works.

If you create a new Symbol using the Symbol function, you will get a unique symbol every time. Example:

const sym1 = Symbol("x");
const sym2 = Symbol("x");
sym1 === sym2; // returns false

If you want to use a global symbol, you will have to define it using Symbol.for as well:

const sym = Symbol.for("x");    

let obj = {
  [sym]: "val"
}
    
console.log(obj[Symbol.for("x")]); // "val"
console.log(obj[sym]); // "val"
const sym = Symbol("x");    

let obj = {
  [sym]: "val"
}
    
console.log(obj[Symbol("x")]); // undefined
console.log(obj[sym]); // "val"
nils
  • 25,734
  • 5
  • 70
  • 79