Es6-Symbol

Today, I saw the strange word “Symbol” in my study.

Symbol is a new primitive data type for Es6. The Chinese translation is “symbol”, in the application means “unique value”. Let’s get to know it together! (the following code is verified by me in vscode oh, ensure correct)

1. Why does Symbol appear

To solve the problem of conflicting attribute names of objects. Object attribute names in ES5 are all strings. When you use objects provided by others, or others use objects provided by you, it is easy to overwrite or rewrite the attribute names. Using Symbol works perfectly because it is essentially a unique identifier that can be used as a unique attribute name for an object.

let a = { sym:'hi' } let sym = Symbol() a[sym] = 'hello'; console.log(a.sym); Hi console.log(a[sym]); // Output: helloCopy the code

Note: The “.” dot operator cannot be used when the Symbol value is used as the attribute name of an object. Because the dot operator is always followed by a string, the runtime does not read the value referred to by sym as the identity name, but the SYm string. So when defining a property inside an object using the Symbol value, the Symbol must be placed in square brackets.

let bol = Symbol();
let b = {
    [bol]:'hello'
}
Copy the code

Object. DefineOroperty (obj, prop, desc); Object. DefineOroperty (Object.

Where obj is the current object for which the property needs to be defined, prop is the name of the property for which the property needs to be defined, and desc is the property descriptor.

let sym = Symbol() let a = {} Object.defineProperty(a,sym,{value:'hello'}) console.log(a[sym]); // Output: helloCopy the code

2. The definition of Symbol

The Symbol value is generated by the Symbol function, which takes a string as an argument that describes the Symbol value. Because the argument is a string, it can be defined as null. The main purpose of this parameter setting is to make it clear which Symbol value is displayed on the console or converted to a string.

In the following example bol and BOLl are both return values of the Symbol function with the same parameters, but they are not equal. Because the parameter in the Symbol function only represents a description of the current Symbol value.

let sym = Symbol(); let bol = Symbol('id'); let boll = Symbol('id'); Console. log(typeof sym); // Symbol console.log(BOL == boll); // Output result: falseCopy the code

Read the description of Symbol

In the following code, bol is described as a string ID.

Reading this description requires an explicit conversion of the Symbol value to a string. Here’s an example:

let bol = Symbol('id'); console.log( String(bol) ); // Symbol(id) console.log(bol.tostring ()); // Symbol(id)Copy the code

But obviously the above method is not very convenient, so ES2019 provides a Symbol instance attribute description, which can directly return the description of the Symbol. Here are some more examples:

let bol = Symbol('id'); console.log(bol.description); // Output result: fooCopy the code

3. Some of the characteristics of Symbol

  1. The most important feature of the Symbol data type is uniqueness. It can be concluded from the above example.

  2. Another characteristic is concealment.

    • Through the for… In, for… Of circulation, or Object. The keys (), Object, getOwnPropertyNames (), JSON. The stringify () is not to be able to access the Symbol. Here are two examples:

      ``` let sym = Symbol() let a = { [sym]:'how are yuo' } for(let item in a){ console.log(a[item]); ``` ``` let sym = Symbol() let a = {[sym]:'how are yuo'} for(let item in a){console.log(a[item]); } console.log(Object.keys(a)); // Output result: [] ' ' 'Copy the code
    • But it is not private property of the Object, through the Object. The getOwnPropertySymbols () method is all can access to the specified Object Symbol attribute names. This method returns an array whose members are all the Symbol values used as attribute names for the current object (as syM in the following example).

      ``` let sym = Symbol() let a = { [sym]:'how are you' } let arr = Object.getOwnPropertySymbols(a); console.log(arr); [Symbol()] console.log(arr[0]); Symbol () console.log(a[arr[0]]); // Output result: how are you ' 'Copy the code
    • You can also use a new API, reflecti.ownkeys (), which returns all types of key names in an object, including regular key names (strings) and Symbol key names. Example:

      let sym = Symbol('sym'); let a = { [sym]:'i', next:'am', nextt:'fine' } console.log(Reflect.ownKeys(a)); ['next', 'nextt', Symbol(sym)]Copy the code

      The reflect.ownkeys () method obviously returns an array of all the key names (that is, property names) in the object.

Therefore, we can take advantage of its hidden features to define methods for objects that are not private but that we want to use only internally.

4. The Symbol value can also be global

ES6 also provides symbol.for () and symbol.keyfor () methods.

  • The symbol.for () method takes a string as an argument, just like Symbol(), except that when called, it checks to see if the parameter is available as a Symbol for the description, returns the Symbol if it is available, and creates a new Symbol and registers it globally.

    • Symbol () has no registration mechanism, so each call returns a different value.

    • Symbol.for() has a registration mechanism, and the name registered for the Symbol value is global, so it can be called repeatedly.

    ``` let one = Symbol.for('sym'); let two = Symbol.for('sym'); console.log(one == two); So, the Symbol values created using symbol.for () are equal as long as the strings used as arguments are the same.Copy the code
  • The symbol.keyfor () method returns a key (the string argument above) of the globally registered value of Symbol type.

    ``` let one = Symbol.for('sym'); console.log(Symbol.keyFor(one)); Sym let two = Symbol('sym'); sym let two = Symbol('sym'); console.log(Symbol.keyFor(two)); // Undefined because two is the registered Symbol value ' 'Copy the code