Reference articles: Rookie Tutorial, Introduction to ECMAScript 6 (Ruan Yifeng)

An overview of the

1.ES5 Except for the class array object (the name of the class array object can be a number, the object must have the length attribute, and the object attribute can be accessed by array subscript, but not by dot), the object attribute name is string, which is easy to cause the attribute name conflict. In addition, JavaScript is a weakly typed language, and property name conflicts are not reported. Property values at the end of the code execution order will overwrite previous property values (property values can be easily tampered with), so the property of the object is not guaranteed to be what we want;

2.ES6 introduces the Symbol data type to solve the problem of object attribute name conflict.

Symbol represents a unique value. It is a primitive data type and cannot be used as New

4. After ES6, JavaScript has 7 data types: Number, String, Boolean, NULL, undefined, Object, Symbol

Basic usage

The Symbol stack cannot use the new command because Symbol is a primitive data type, not an object. You can take a string as an argument to provide a description of the newly created Symbol that can be displayed on the console or used as a string for easy differentiation.

let name = Symbol("name");
console.log(name);  // Symbol(name)
console.log(typeof name);  // "symbol"
Copy the code

The characteristics of

The Symbol stack cannot use the new command because Symbol is a primitive data type, not an object.

2.Symbol represents a unique value, so two symbols with the same parameter are not equal.

// let name1 = Symbol(); let name2 = Symbol(); Name1 === name2 // false name1 === name2 // false // let name1 = Symbol('foo'); let name2 = Symbol('foo'); name1 === name2 // false name1 === name2 // falseCopy the code

3.Symbol cannot perform implicit type conversion

let name = Symbol('foo'); Console. log(" Hello, "+ name); // Uncaught TypeError: Cannot convert a Symbol value to a string console.log(' Hello,${name} '); TypeError: Cannot convert a Symbol value to a string console.log(name +1;) TypeError: Cannot convert a Symbol value to a string console.log(name +1;) Uncaught TypeError: Cannot convert a Symbol value to a numberCopy the code

4. The Symbol value can be explicitly converted to a string

let name = Symbol('foo');
console.log(String(name));  // "Symbol(foo)"
console.log(name.toString()); // "Symbol(foo)"
Copy the code

5. The value of Symbol cannot be converted to numbers

let name = Symbol('foo');
console.log(Number(name));  
// Uncaught TypeError: Cannot convert a Symbol value to a number
Copy the code

6.Symbol values can be converted to Boolean values

let name = Symbol('foo'); Boolean(name ) // true ! name // falseCopy the code

6. The Symbol variable cannot be used as a webStorage key

let ss = Symbol(); Localstorage.setitem (ss," hahaha "); Uncaught TypeError: Cannot convert a Symbol value to a stringCopy the code

Symbol Application Scenario

1. As an object attribute name

1.1 Symbol as object property name bullet point

1. Do not use the. Operator. Use square brackets instead.

– Objects in ES5. The. Operator recognizes the property name as a string and creates a new property name for the object, indistinguishable from the Symbol property

– Attribute names with double quotes in brackets represent string attributes, and attribute names without double quotes represent Symbol attributes to distinguish between the two

let sy = Symbol(); // let syObject = {}; syObject[sy] = "symbol"; console.log(syObject); / / {Symbol () : "Symbol"} / / writing 2 let syObject = {(sy) : "Symbol"}; console.log(syObject); / / {Symbol () : "Symbol"} / / writing 3 let syObject = {}; Object.defineProperty(syObject, sy, {value: "symbol"}); console.log(syObject); // {Symbol(): "Symbol "} // "symbol" syObject.sy; // undefined // syObject.sy ==> syObject["sy"]Copy the code

2. When the Symbol value is used as the attribute name, the attribute is public, not private, and can be accessed outside the class. But not in the for… In, for… Of the loop, will not be the Object. The keys (), Object. GetOwnPropertyNames () returns. If you want to read to the Symbol attribute of an Object, you can through the Object. The getOwnPropertySymbols () and Reflect ownKeys () to get.

let sy = Symbol(); let syObject = {}; syObject[sy] = "symbol"; console.log(syObject); // {Symbol(): "symbol"} for (let i in syObject) { console.log(i); } // No output object.keys (syObject); // [] Object.getOwnPropertyNames(syObject) // [] Object.getOwnPropertySymbols(syObject); // [Symbol()] Reflect.ownKeys(syObject); // [Symbol()]Copy the code

2. Define constants

A constant defined with const does not guarantee that its value is unique. This can be problematic in some judgment statements, such as

const COLOR_RED = "red"; const COLOR_YELLOW = "yellow"; const COLOR_BLUE = "blue"; const MY_BLUE = "blue"; function ColorException(message) { this.message = message; this.name = "ColorException"; } function getConstantName(color) { switch (color) { case COLOR_RED : console.log(1); return "COLOR_RED"; case COLOR_YELLOW : console.log(2); return "COLOR_YELLOW "; case COLOR_BLUE: console.log(3); return "COLOR_BLUE"; case MY_BLUE: console.log(4); return "MY_BLUE"; default: console.log(5); throw new ColorException("Can't find this color"); } } try { var color = MY_BLUE; var color1 = COLOR_BLUE; var colorName = getConstantName(color); var colorName1 = getConstantName(color1); } catch (e) { var colorName = "unknown"; console.log(e.message, e.name); // Pass the exception object to the error handler}Copy the code

In the code above, the constant MY_BLUE and the constant COLOR_BLUE both match the first executed constant with a value of blue. The console prints 3 twice. The program uses Symbol to define constants, which ensures that the values of the constants are not equal

const COLOR_RED = Symbol("red"); const COLOR_YELLOW = Symbol("yellow"); const COLOR_BLUE = Symbol("blue"); const MY_BLUE = Symbol("blue"); function ColorException(message) { this.message = message; this.name = "ColorException"; } function getConstantName(color) { switch (color) { case COLOR_RED : console.log(1); return "COLOR_RED"; case COLOR_YELLOW : console.log(2); return "COLOR_YELLOW "; case COLOR_BLUE: console.log(3); return "COLOR_BLUE"; case MY_BLUE: console.log(4); return "MY_BLUE"; default: console.log(5); throw new ColorException("Can't find this color"); } } try { var color = MY_BLUE; Var color1 = COLOR_BLUE; Var colorName = getConstantName(color); var colorName1 = getConstantName(color1); } catch (e) { var colorName = "unknown"; console.log(e.message, e.name); // Pass the exception object to the error handler}Copy the code

The above code console printed 4 and 3 successively, indicating that the result of our judgment statement matching is correct.

The method of Symbol

1.Symbol.for()

Use to point the same Symbol variable to the same Symbol value.

let a1 = Symbol.for('a');
let a2 = Symbol.for('a');
a1 === a2  // true
typeof a1  // "symbol"
typeof a2  // "symbol"

let a3= Symbol("a");
a1 === a3      // false
Copy the code

Symbol() and symbol.for () share the following similarities: 1. Symbol() and Symbol. For () : 1.Symbol() defines a new value every time. 2. The value defined by symbol.for () will first check whether the given description already exists. If not, a new value will be created, and this value is registered in the global environment for search.

2.Symbol.keyFor()

Function: Checks if the Symbol value of the string parameter name is registered, and returns the key of a registered Symbol value

let a1 = Symbol.for("a");
Symbol.keyFor(a1);    // "a"

let a2 = Symbol("a");
Symbol.keyFor(a2);    // undefined
Copy the code

A1 is already registered with symbol.for (), so the key returned is “a”. A2 is not registered, so undefined is returned

The attribute of Symbol

1.Symbol.prototype.description

Description is used to return a description of the Symbol data

// Symbol()定义的数据
let a = Symbol("acc");
a.description  // "acc"
Symbol.keyFor(a);  // undefined

// Symbol.for()定义的数据
let a1 = Symbol.for("acc");
a1.description  // "acc"
Symbol.keyFor(a1);  // "acc"

// 未指定描述的数据
let a2 = Symbol();
a2.description  // undefined
Copy the code

The difference between the description property and the symbol.keyfor () method is that description returns a description of all Symbol type data, whereas symbol.keyfor () returns only globally registered descriptions of symbol.for ()