5

I am learning about JavaScript symbols and from what I have read they are used to protect object property key overwrites. In the following code I create two symbols of the same variable name and use them as object keys. I want to know how to access the data assigned to either one of the "symbol" keys at the bottom of the program. If I'm misunderstanding the purpose of symbols altogether please point it out.

var id = Symbol("my id");             // Create a Symbol

var user = {

    name:"Bob",
    age:30,
    [id]:"my id 12345"               // Use it as a property key and add some data
}

var id = Symbol("my different id"); // Create a new Symbol

user[id] = "my different id 9876"   // Assign it with some new data

console.log(user);

/* The object contains both symbols. No overwrites!


{

    name: "Bob", 
    age: 30, 
    Symbol(my id): "my id 12345", 
    Symbol(my different id): "my different id 9876"

}


*/
William
  • 4,422
  • 17
  • 55
  • 108
  • 1
    use .for method `var id = Symbol.for("my id")` – disstruct Mar 06 '17 at 23:30
  • 1
    That gets the symbol but I want the object property data assigned to it. Sorry I wasn't clear. I will reword my question – William Mar 06 '17 at 23:38
  • 1
    Don't overwrite the original value of `id` if you want to access the same property. – jfriend00 Mar 06 '17 at 23:48
  • 1
    @jfriend00 If symbols aren't there to protect that kind of behavior then what are they for ? – William Mar 06 '17 at 23:48
  • 1
    @William - Symbols provide unique private names that do not conflict with strings - ever. So, no string property access can ever accidentally overwrite or access a property name that was established with a symbol. And, nobody can ever create that symbol again as they are unique on a given JS engine. You can read this article [Metaprogramming in ES6: Symbols and why they're awesome](https://www.keithcirkel.co.uk/metaprogramming-in-es6-symbols/) for more info. – jfriend00 Mar 06 '17 at 23:50
  • And, if you use `Symbol.for()` then symbols can be automatically created or looked up in a global registry that everyone can share. So, they can also be used a safe, sharable and global values. – jfriend00 Mar 06 '17 at 23:55
  • @bergi then what are they for ????? "nope" doesn't add anything to the conversation. – William Mar 07 '17 at 00:27
  • @jfriend00 "A symbol value may be used as an identifier for object properties; this is the data type's only purpose" --->https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol – William Mar 07 '17 at 00:47
  • @William - Yeah, so why is that comment addressed at me? It doesn't have to be used as an object property name. It could be used as a guaranteed unique key in a Map object, for example. – jfriend00 Mar 07 '17 at 01:02
  • @jfriend00 I was just trying to determine the underline use case and because the MDN link I posted said properties I assume "object" and didn't even think of maps. I was just trying to get you to talk more (I guess) so I could understand. :) – William Mar 07 '17 at 02:55

2 Answers2

5

If I understand you right, you need

var id = Symbol.for("my id");

var user = {
    name:"Bob",
    age:30,
    [id]:"my id 12345"     
}

var id = Symbol.for("my different id");

user[id] = "my different id 9876"

console.log(user[Symbol.for("my id")]); 
console.log(user[Symbol.for("my different id")]);

The id variable is reassigned, so you can use it just to get "my different id 9876" Symbols will not be reassigned.

disstruct
  • 673
  • 3
  • 8
  • Yes, this is it. I don't know who down voted this answer. It wasn't me. – William Mar 06 '17 at 23:55
  • :) Doesn't matter – disstruct Mar 06 '17 at 23:55
  • I guess the next question is how do you access them if the string identifier is the same ? : O ..... It looks like you can't. I suppose Symbols should have some kind of hash as their string identifier so they do not get overwritten. ha! – William Mar 06 '17 at 23:59
  • Yep. I don't know for sure how symbols are implemented, but I think of them as a hash – disstruct Mar 07 '17 at 00:02
  • Don't use `Symbol.for` unless you know what its purpose is. – Bergi Mar 07 '17 at 00:23
  • Berni - I asked what its purpose is and all the answers are over complicated jargon. I'm asking for basic simply utility. Do you have an answer? – William Mar 07 '17 at 00:30
3

I create two symbols of the same variable name and use them as object keys.

Why would you do that? Symbols are meant to provide unique, non-enumerable property keys to avoid name clashes. They have two distinct identities, and should be used as constants that you can reference from where you need them. You can even create multiple distinct symbols with the same description:

const idA = Symbol("my id");
const idB = Symbol("my id");
console.log({[idA]: 12345, [idB]: 9876});

I want to know how to access the data assigned to either one of the "symbol" keys at the bottom of the program.

Just keep a reference to both of them:

const myId = Symbol("my id");
const myDifferentId = Symbol("my different id");

var user = {
    name:"Bob",
    age:30,
    [myId]:"my id 12345"
};
user[myDifferentId] = "my different id 9876";

console.log(user);
console.log(user[myId], user[myDifferentId]);

If you did not keep a reference, you can also access them using the Object.getOwnPropertySymbols function.

Community
  • 1
  • 1
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • 1
    How do you avoid name clashes if you can't be protected from overwriting the key ? How is "I have read they are used to protect object property key overwrites " different than "Their only purpose is to provide unique, non-enumerable properties to avoid name clashes." – William Mar 07 '17 at 00:35
  • 1
    Because you'd need to have access to the symbol, and need to deliberately use it. Name collisions have nothing to do with property accessibility and information hiding. It's just that with string property names, you cannot prevent someone else from accidentally using the same - with symbols, you can. – Bergi Mar 07 '17 at 00:37
  • 1
    Is there a very direct and simple example anywhere that demonstrates this in use? I just don't understand until I see it. – William Mar 07 '17 at 00:40
  • OK, maybe you meant the right thing, but I understood it as wanting private properties that are non-writable for others, to provide encapsulation. That's not what symbols do. – Bergi Mar 07 '17 at 00:41
  • If keys are created on objects with Symbols I know the assigned property data can be overwritten. I was not asking that – William Mar 07 '17 at 00:42
  • Notable thing is key created with symbol is not considered when calling `Object.keys()`. And so, we cannot access the key value using dot operator like `user.id` – Jeyanth Jul 21 '22 at 09:12
  • @Jeyanth Whether you can access a property using dot syntax has nothing to do with `Object.keys` – Bergi Jul 21 '22 at 12:03