ES6 has introduced the new feature of Symbol, so it should be introduced to solve the problem. So what kind of problems can Symbol solve, and how to use Symbol reasonably, with these problems, we will talk about the new ES6 feature of Symbol today.

Symbol is the base data type

Symbol is a new feature in ES6. Symbol is a basic data type in javascript, along with numeric, string, and Boolean types.

const num1 = Number(1)
console.log(num1)

const num2 = 1;

console.log(num1 === num2);
Copy the code

We rarely use Number(1) to create a numeric 1 and assign it to num1. We usually prefer the easy way of defining primitives with 1, For Symbol, we can only use Symbol() to create a Symbol type. So you can see why Symbol has no constructor.

How do I create Symbol type values

The Symbol() function and symbol.for () method are used to create a Symbol value.

Symbol () function

const symb1 = Symbol(a);console.log(symb1)
Copy the code

The output is as follows

Symbol()
Copy the code

Symbol is not an object, it is just a basic data type.

const symb1 = new Symbol(a);Copy the code
TypeError: Symbol is not a constructor
Copy the code

Each Symbol value returned from Symbol() is unique. Use Symbol() to create a new Symbol value and use an optional string as its description.

const symb1 = Symbol("symbol description");
console.log(symb1)
Copy the code
const symb1 = Symbol("machine learning");
const symb2 = Symbol("machine learning");

console.log(symb1 == symb2) //false
Copy the code

It can be seen from the above code that we define two symbols with exactly the same description. The result is that the two symbols are different.

Note that when we use a Symbol value for the object property name, we need to add square brackets to the Symbol value.

const symb1 = Symbol("symbol description");
// console.log(symb1)

let tut = {
    name:"basic machine learning",
    [symb1]:new Date()}for (prop in tut){
    console.log(prop)
    console.log(tut[prop])
}
Copy the code
name
basic machine learning
Copy the code

If a symbol value is used as an identifier in an attribute assignment statement, the attribute is anonymous and not enumerable. Therefore, when we use prop in tut to iterate through all properties of the object tut, we find that the symbol value definition attribute has no edge to display. This is mainly because this attribute is not enumerable and does not exist in the loop structure for(… in …) In the Object, as in the same getOwnPropertyNames () returns an array of type with the Symbol is also unable to find worth attribute identifier.

console.log(Object.getOwnPropertyNames(tut))
Copy the code
[ 'id', 'name', 'author' ]
Copy the code

Through this Object. GetOwnPropertySymbols () will get objects using numerical as identity Symbol type attributes.

console.log(Object.getOwnPropertySymbols(tut))//[ Symbol(id) ]
Copy the code

Symbol. The for () method

One way to create this is to use symbol.for ()

const symb1 = Symbol.for("create time");
Copy the code

Globally shared Symbol

The value of the Symbol type is not necessarily unique, as in the following case. When we use symbol. for to create a Symbol value and give it a string, the string is no longer a description, but an index is created in the global Symbol corresponding to a Symbol value, so the same index points to the same Symbol value. The following code proves that searching the same index in the global Symbol yields the same value for both Symbol types.

const symb1 = Symbol.for("create time");
const symb2 = Symbol.for("create time");

console.log(symb1 === symb2);//true
Copy the code
console.log(Symbol.keyFor(symb1));//create time
Copy the code
const symb1 = Symbol.for("create time");
const symb2 = Symbol.for("create time");
const tut1 = {
    name:"basic pyTorch",
    [symb1]: new Date()}console.log(tut1[symb2])
Copy the code

Application scenario of Symbol

Let’s take a look at how Symbol can be used in real development to solve problems such as overwriting or ID conflicts.

Extended object properties

By now, I think you have probably understood the concept of Symbol and how to create and use it. Then the next step is the focus, that is, how to use Symbol to solve the problem on which occasions. Avoid overwriting the original attributes, so we can use Symbol type value as the attribute name when we add attributes to complex objects, so as to avoid overwriting attributes.

const tut = {
    id:123.name:"basic machine learning".author:"matthew"
};


tut.id = 789;
console.log(tut.id);/ / 789
Copy the code
const tut = {
    id:123.name:"basic machine learning".author:"matthew"
};

const idSymbol = Symbol("id")

tut[idSymbol] = 789;
console.log(tut.id); \ \123
Copy the code

Can be used as static variables

The problem in the first section of code is that when banana = “yellow “also goes to the branch BLUE, because BLUE is not unique as a string value. In this case we can use the uniqueness of Symbol.

const RED = 'red';
const YELLOW = 'yellow';
const BLUE = 'blue';

function getLogLevel(color){
    switch(color){
        case RED:
            return 'error';
        case YELLOW:
            return 'warning';
        case BLUE:
            return 'info';
        default:
            console.log("unkown level ")}}const banana = "yellow";

console.log(getLogLevel(banana))// warning
Copy the code
class Sequence{
    constructor(){
        this.length = 0
    }
    add(layername,layer){
        this[layername] = layer;
        this.length++
    }
}


let model = new Sequence();
model.add("input"."liner");
model.add("hidden layer"."dense layer")
model.add("output"."softmax")

for (layer in model){
    console.log(model[layer])
}
Copy the code

Avoid overwriting and facilitate team development

class AlertService{
    constructor(){
        this.alerts = {}
    }

    addAlert(symbol, alertText){
        this.alerts[symbol] = alertText
        this.renderAlert();
    }

    removeAlert(symbol){
        delete this.alerts[symbol]
    }

    renderAlert(){}}const alertService = new AlertService()

class MyComponent{
    constructor(thing){
        this.componentId = Symbol(thing)
    }

    errorHandler(msg){
        alertService.addAlert(this.componentId,msg)
    }
}

let userList = MyComponent("listComponent")
let itemList = MyComponent("listComponent")

let registerForm = MyComponent("inputComponent");

userList.errorHandler("some text 1");
itemList.errorHandler("some text 2")
Copy the code

This.component.ponentid = Symbol(thing) this.component.ponentid = Symbol(thing) this.component.ponentid = Symbol(thing) this.component.ponentid = Symbol(thing) this.component.ponentid = Symbol(thing) This is a good way to avoid conflict. By now, we all have a good understanding of what a Symbol is and how to use it.