Introduce a,

Symbol is a new data type in ES6, which is a basic data type. The description of Symbol type in MDN is as follows: Data type “Symbol” is a primitive data type. The property of this type is that the value of this type can be used to create anonymous object attributes. This data type is usually used as the key value of an object property — when you want it to be private.


symbolData types have a very specific purpose and are distinguished by their simplicity of functionality; asymbolInstances can be assigned to an lvalue variable, and types can be checked by identifiers, which is all it has.

This description almost completely explains the purpose of this new datatype: as a key for an object or a Map, it ensures that your object or Map’s key is not duplicated (this can be really useful in some scenarios). Because this data type is new in ES6, there is no polyfill.

Second, usage,

Object 1.

1.1 Common Usage

What you can use to create symbols is a class-like function Symbol() that creates instances of the Symbol data type. Note that the new command cannot be used before the Symbol function, otherwise an error will be reported. This is because the generated Symbol is a primitive type value, not an object. That is, because the Symbol value is not an object, attributes cannot be added. Basically, it’s a data type similar to a string. A value with the data type “symbol” can be called a “symbol type value”. In a JavaScript runtime environment, a Symbol type value can be created by calling the function Symbol(), which dynamically generates an anonymous, unique value. The only reasonable use of the Symbol type is to store the value of Symbol in a variable and then use the stored value to create object properties. The simplest way to write a key as an object is as follows:

var  privateKey  = Symbol(a);var obj = {
    [privateKey] : 'hero'
}
/ / access
obj[privateKey]  //hero
Copy the code

It’s usually used when we’re accessing a property in a key-value object. Notation to get the corresponding value, but using. ES6 uses [] as the key of the Symbol instance. ES6 uses [] as the key of the Symbol instance. ES6 uses [] as the key of the Symbol instance. More suitable for storing key-value pairs of data, you can refer to the Java Map data structure).

var identity = Symbol(a)var obj = {
    name : 'john',
    [identity] : 'hero'
}
obj.name   //'john'
obj[name]  //'john'
obj.identity   //undefined
// When we use. Undefined is returned because the key does not exist
obj[identity]  //'hero'
Copy the code
1.2 Traverse the object containing Symbol

However, when we traverse an object, when we use for in or for of methods, Symbol with key or value will not appear in the traversal result. Also is not the Object. The keys (), the Object. The getOwnPropertyNames (), JSON. The stringify () returns. But with the Symbol appear together there is a way to get to its value: Object. GetOwnPropertySymbols, can get all the Symbol of specified Object attribute names. Object. GetOwnPropertySymbols method returns an array, the member is the all of the current Object is used as the Symbol value of the property name.

const obj = {};
let a = Symbol('a');
let b = Symbol('b');

obj[a] = 'Hello';
obj[b] = 'World';

const objectSymbols = Object.getOwnPropertySymbols(obj);

objectSymbols
// [Symbol(a), Symbol(b)]
Copy the code

However, we also have an API that can be used to Reflect all the keys in an object, including normal keys and Symbol keys: reflect.ownkeys. [Reference from Ruan Yifeng’s ES6 tutorial]

let obj = {
  [Symbol('my_key')]: 1.enum: 2.nonEnum: 3
};

Reflect.ownKeys(obj)
// ["enum", "nonEnum", Symbol(my_key)]
Copy the code
1.3 the reuse Symbol

Symbol is designed to give us a special value that is never repeated, but there are situations where the same Symbol is needed. The API is always more than we think. Symbol has a method: Symbol.for, which takes a string as an argument and searches for a Symbol value named for that argument. If so, return the Symbol, otherwise create and return a Symbol with the name of the string.

let s1 = Symbol.for('foo');
let s2 = Symbol.for('foo');

s1 === s2 // true
Copy the code

The API works like this: Symbol. For () and Symbol() both generate new symbols. The difference is that the former will be registered in the global environment for search, while the latter will not. Symbol.for() does not return a new Symbol value each time it is called. Instead, it checks to see if the given key already exists and creates a new value if it does not. For example, if you call symbol. for(“cat”)30 times, the same Symbol will be returned each time, but calling Symbol(“cat”)30 times will return 30 different symbols. Similarly, the Symbol. KeyFor API returns the key of a registered Symbol type value.

let s1 = Symbol.for("foo");
Symbol.keyFor(s1) // "foo"

let s2 = Symbol("foo");
Symbol.keyFor(s2) // undefined
// Because s2 is not created with symbol.for (), it cannot be obtained using symbol.keyfor ()
Copy the code

2. General method

Of course, in order to make it easier to distinguish between symbols, we usually pass a parameter to Symbol() to distinguish between symbols, such as Symbol(‘name’), which is more convenient for debugging during development

let symbol1 = Symbol('name');
let symbol12 = Symbol('age');

symbol1 // Symbol(name)
symbol2 // Symbol(age)
// The Symbol above is only the return value, even if the return value is the same, does not mean that the two symbols are the same!

symbol1.toString() // "Symbol(name)"
symbol2.toString() // "Symbol(age)"

// The Symbol value cannot be evaluated with other types of values.
Symbol('hero') + ' hello'  //TypeError: can't convert symbol to string
// We have to explicitly convert Symbol to a string before we can add it to other numbers or strings
Symbol('hero').toString() + ' hello'     //"Symbol(hero) hello"
//Symbol can be converted to Boolean values
Boolean(Symbol('hero'))     //true
//Symbol cannot be converted directly to numbers in some way
Number(Symbol('hero')) // TypeError
Copy the code

Three, endnotes

Symbol appears for a very simple purpose, is as an object key value, some commonly used methods are very easy to understand, the key is that this can effectively eliminate magic string and magic number ah hello 😂.