Home >Web Front-end >JS Tutorial >Detailed explanation of Symbol type in Javascript
According to the specification, the object attribute key can only be string type or symbol type, not number or boolean, only string and There are two types of symbols.
We generally compare attribute strings, now let’s look at the advantages that the symbols type brings to us.
The "Symbol" value represents a unique identifier using the given name. Values of this type can be created like this: Symbol(name)
:
// id is a symbol with the name "id" let id = Symbol("id");
Symbols ensure uniqueness and will produce different values even if we use the same name. For example, here are two symbols with the same name, both of which are not equal:
let id1 = Symbol("id"); let id2 = Symbol("id"); alert(id1 == id2); // false
If you are familiar with Ruby or other languages and there are the same types of symbols, don't be misled, Javascript symbols are different.
symbol allows the creation of hidden properties of an object so that other code cannot accidentally access or overwrite them.
For example, if we want to store the "identifier" of the object user, we can create a symbol of id:
Let user = { name: “John” };
Let id = Symbol("id");
user[id] = "ID Value"; alert( user[id] ); // we can access the data using the symbol as the key
Now let's imagine that another script wants to add its own "id" attribute to the user object for its own purpose. It may be another Javascript library, so they don't know each other at all.
No problem, you can create your own Symbol("id")
.
The code is as follows:
// ... let id = Symbol("id"); user[id] = "Their id value";
There is no conflict because the symbols are always different, even with the same name. Note that if we use the string "id" instead of symbol to achieve the same purpose, there will be a conflict:
let user = { name: "John" }; // our script uses "id" property user.id = "ID Value"; // ...if later another script the uses "id" for its purposes... user.id = "Their id value" // boom! overwritten! it did not mean to harm the colleague, but did it!
If we use symbol in a literal object, we need Use square brackets:
let id = Symbol("id"); let user = { name: "John", [id]: 123 // not just "id: 123" };
because we need the symbol variable value named "id", not the string "id".
The symbol attribute does not participate in the for..in loop, for example:
let id = Symbol("id"); let user = { name: "John", age: 30, [id]: 123 }; for(let key in user) alert(key); // name, age (no symbols) // the direct access by the symbol works alert( "Direct: " + user[id] );
At this time, part of the concept is generally hidden, if other scripts or libraries , nor is it expected to access the symbol property.
In contrast, Object.assign copies both character attributes and symbol attributes.
let id = Symbol("id"); let user = { [id]: 123 }; let clone = Object.assign({}, user); alert( clone[id] ); // 123
There is no contradiction between the two. This is how the specification is designed. The idea is that when we clone or merge objects, we usually want the symbol attribute to be copied as well.
Other types of attribute keys are forced to be converted to strings:
The keys in the object can only use strings or symbols, and other types are forced to be converted to strings.
let obj = { 0: "test" // same as "0": "test" } // both alerts access the same property (the number 0 is converted to string "0") alert( obj["0"] ); // test alert( obj[0] ); // test (same property)
Usually, all symbols are different, but sometimes we want the symbols of the same noun to be the same. For example, if we want to access the symbol with the noun "id" in different parts of the application, of course it needs to be the same.
This can be achieved through global symbol registration. We can create them first and then access them, and ensure that the same symbol is obtained through repeated access with the same noun.
Create or read in registration, the usage syntax is: symbol.for(name)
, example:
// read from the global registry let name = Symbol.for("name"); // if the symbol did not exist, it is created // read it again let nameAgain = Symbol.for("name"); // the same symbol alert( name === nameAgain ); // true
The symbol in registration is called global symbol, if We have application-wide symbols that are accessible to all code and can use global symbols.
Other programming languages, like Ruby, each noun has a single symbol. In JavaScript, we know that it is the global symbol.
For global symbols, there is not only Symbol.for(name)
, which returns the symbol according to the name, but also the opposite call: Symbol.keyFor (name)
, the function is opposite: return the name according to the global symbol.
Example:
let sym = Symbol.for("name"); let sym2 = Symbol.for("id"); // get name from symbol alert( Symbol.keyFor(sym) ); // name alert( Symbol.keyFor(sym2) ); // id
Internal implementation of Symbol.keyfor uses global symbol registration and searches for symbol names based on symbol.
So it has no effect on non-global symbols. If it is not a global symbol, it will not be found and undefined will be returned.
Example:
alert( Symbol.keyFor(Symbol.for("name")) ); // name, global symbol alert( Symbol.keyFor(Symbol("name2")) ); // undefined, non-global symbol
Non-global symbol, the name is only used for debugging purposes.
There are many system symbols inside Javascript, and we can use them to adjust various aspects of the object.
Here are some commonly used symbols:
Symbol.hasInstance
Symbol.isConcatSpreadable
Symbol.iterator
Symbol.toPrimitive
…
Example: Symbol.toPrimitive
is used to describe objects when converting them to basic types. If you continue to study Javascript in depth, you will gradually become familiar with the others.
symbol is a basic type that implements unique identification
by calling symbol(name)
Create symbol
We create a field that can only be accessed by people who know the corresponding symbol. It is very useful to use symbol
symbol will not appear In the for..in result
symbol created using symbol(name) is always different, even if the name is the same. If you want symbols with the same name to be equal, use global registration
symbol.for(name) to return a global symbol with a given name, and multiple calls to return the same symbol
Javascript has system symbols, accessed through Symbol.*. We can use them to modify some built-in behaviors.
Technically, symbols are not 100% hidden. There is a built-in method Object.getOwnPropertySymbols(obj)
to get all symbols.
There is also a methodReflect.ownKeys(obj)
Returns all keys of the object, including symbol.
So it’s not really hidden. But most library built-in methods and syntax constructs follow a common convention that they are hidden, and if someone explicitly calls the above method, he may fully understand what he is doing.
The above is the detailed content of Detailed explanation of Symbol type in Javascript. For more information, please follow other related articles on the PHP Chinese website!