Symbol
type is a special type in JavaScript
. Specially, all Symbol
type values are different from each other. We can use "Symbol" to represent a unique value. The following is an example of creating a Symbol
object:
let id = Symbol();
In this way, we create a Symbol
type value and store this value in the variable id
.
When we create a Symbol
type variable, we can pass in some strings with seconds attributes in the parameters to describe the purpose information of this variable.
For example:
let id1 = Symbol('The id of Xiao Ming who is crazy and cool'); let id2 = Symbol('Low-key, luxurious and connotative Tingting's id');
Symbol
types are different at any time, even if they have the same description information, the description is just a label and has no other purpose For example:
let id1 = Symbol('id'); let id2 = Symbol('id'); console.log(id1==id2);//
The meaning of the false label, I personally think it is related to the fact that Symbol
cannot intuitively see the internal specific value. By adding a description information, we can have a more intuitive understanding of the use of variables. understanding.
Most types in JavaScript
can be directly converted to a string type for output, so we cannot intuitively see what its value is. For example, we can directly use alert(123)
to convert the number 123
Convert to string popup.
However, the Symbol
type is special and cannot be converted directly, for example:
let id = Symbol(); alert(id);//Error report, the Symbol type cannot be converted
to a string. Symbol
type in JavaScript
cannot be converted to a string because of its inherent "language protection" mechanism to prevent language confusion, because strings and Symbol
are essentially different There is a difference and one should not be converted into the other.
Just imagine, if Symbol
can be converted to a string, then it becomes a function that generates a unique string, and there is no need for an independent data type.
If we really want to know the value of Symbol
variable, we can use the .toString()
method as follows:
let id = Symbol('this is identification'); console.log(id.toString());//Symbol(this is identification);
Or use the .description
attribute to get the description information:
let id = Symbol('Come on, give me Oli'); console.log(id.description);//Come on, Ollie”
According to JavaScript
specifications, only two types of values can be used as object property keys:
If other types are used, It will be converted to a string type implicitly. The key of the object is introduced in detail in the previous chapter and will not be repeated here.
There are two Symbol
Example 1:
let id = Symbol('id'); let user = {}; user[id] = 'id value';//Add Symbol key console.log(user[id]);//id value
Example 2:
let id = Symbol('id'); let user = { [id]:'id value',//note the square brackets here }; console.log(user[id]);
The above two cases show the use of inserting Symbol
type as a key in the object. It should be noted that when accessing the attribute, you need to use obj[id]
instead of obj.id
, because obj.id
represents obj['id']
.
What will happen if we use Symbol
as the key of the object?
Symbol
in for...in is that if the object uses Symbol
as a key, then Symbol
type properties cannot be accessed using for…in
statement.
For example:
let id = Symbol('id'); let user = { name: 'xiaoming', [id] : 'id', }; for (let key in user) console.log(user[key]);
Execute the above code and get the following results:
> Xiaoming
can find that the value of the [id]
object is not printed out, indicating that in the object attribute list, use for … in
will automatically ignore keys of type Symbol
.
Likewise, Object.keys(user)
will ignore all keys of type Symbol
.
This feature can bring very useful effects, for example we can create properties that only we can use.
Although we have no way to directly obtain the Symbol
key, Object.assign
method can copy all properties:
let id = Symbol(); let obj = { [id] : '123' } let obj2 = Object.assign({},obj); console.log(obj2[id]);
This does not affect the hidden properties of Symbol
, because the copied object still cannot obtain the Symbol
key.
Since Symbol
cannot be directly converted to a string, we have no way to obtain its value intuitively, nor can we obtain the Symbol
attribute of the object through for … in
In other words, without Symbol
variable itself, we have no way Get the corresponding properties inside the object.
Therefore, through the key value of the Symbol
type, we can hide the properties. These properties can only be accessed by ourselves, and no one else can see our properties.
For example:
During the development process, we need to cooperate with our colleague "Zhang San", and this Zhang San created a very easy-to-use tool Tool
. Tool
is an object type. We want to use Zhang San's Tool
for free, and Add some of your own properties based on this.
We can add a Symbol
type key:
let tool = {//Tool written by Zhang San usage: "Can do anything", } let name = Symbol("My tool obj"); tool[name] = "This is my tool"; console.log(tool[name]);
The above example shows how to add your own properties to an object written by others, so why use Symbol
type instead of a regular string?
The reasons are as follows:
tool
is code written by others. In principle, we should not modify other people's code, as this will cause risks;Symbol
, because Symbol
are different;Symbol
type keys, which means that they will not conflict with other people's code;error demonstration:
If we don't use the Symbol
type, the following situation is likely to occur:
let tool = {//Tool written by Zhang San usage: "Can do anything", } tool.usage = "Boom Boom"; console.log(tool.usage);
The above code reuses "usage" and thus rewrites the original attributes, which will cause the original function of the object to be abnormal.
All Symbol
variables are different, even if they have the same label (description).
Sometimes, we want to access the same Symbol
object through a string name (label), for example, we access the same Symbol
in different places in the code.
JavaScript
maintains a global Symbol
registry. We can access the object by inserting a Symbol
object into the registry and giving the object a string name.
To insert or read a Symbol
object into the registry, you need to use Symbol.for(key)
method. If there is an object named key
in the registry, the object will be returned. Otherwise, a new object will be inserted and returned.
For example:
let id1 = Symbol.for('id');//There is no Symbol named id in the registry, create and return let id2 = Symbol.for('id');//There is already a Symbol named id in the registry For the Symbol with id, directly return console.log(id1===id2);//true.
Through Symbol.for(key)
we can use Symbol
object as a global variable and use a string to mark the name of the object.
On the contrary, we can also use Symbol.keyFor(Symbol)
to get the name from the object in reverse.
For example:
let id = Symbol.for('id');//There is no Symbol named id in the registry, create and return let name = Symbol.keyFor(id); console.log(name);//id
Symbol.keyFor()
function can only be used on global Symbol
objects (objects inserted using Symbol.for
). If used on non-global objects, it will return undefined
.
For example:
let id = Symbol('id');//local Symbol let name = Symbol.keyFor(id); console.log(name);//undefined
JavaScript
has many system Symbol
, such as:
Symbol.hasInstance
Symbol.iterator
Symbol.toPrimitive
. They have their own uses. We will gradually introduce these unique variables later.
Symbol
object is unique;Symbol
can add a label and query the entity of the object in the global registry through the label;Symbol
as the key of the object cannot be detected for … in
;Symbol
The global Symbol
object;however, Symbol
is not completely hidden. We can get all Symbol
of the object through Object.getOwnPropertySymbols(obj)
, or get all the keys of the object through Reflect.ownKeys(obj)
.