preface

In early December, I was going to make a note of Ruan’s ECMAScript6 Introduction as a reference, but the article was aborted around the 11th. Why is that? One is that the supervisor recently assigned tasks and had little time to do them. There is another reason is: Nima can not understand ah!!

Recently things are less, back to continue learning, see an interesting thing: Symbol.

ES6 introduces a new primitive data type, Symbol, that represents unique values.

Raw data type?? This reminds me of an earlier question: What are JavaScript data types?

I wrote undefined, NULL, number, string, Boolean, Object. The interviewer asked me, is that all there is to data types? I have a Symbol impression in my mind, but when the interviewer continued to ask about the function of the Symbol, I was speechless, because I really did not know what it is. So the interviewer told me about Symbol:

An overview of the

Object attribute names in ES5 are all strings, which can easily cause attribute name conflicts. For example, if you use an object provided by someone else and want to add a new method to the object (the mixin pattern), the name of the new method may conflict with the existing method. It would be nice if there were a mechanism to ensure that each property name was unique, preventing property name conflicts at all. This is why ES6 introduced Symbol.

Basic usage

let s = Symbol(a);typeof s // => "symbol" 
Copy the code

This seems to be different from the previous generation of object writing, not using the new command, you ask me why? That’s an object, isn’t it? Symbol is a primitive data type. And the object is a parallel relationship ~

We use the Symbol() to create the Symbol, which is very difficult to read. It doesn’t matter. Symbol has already worked out a solution for us:

The Symbol function can take a string as an argument representing a description of the Symbol instance, mainly to make it easier to distinguish when displayed on the console or converted to a string.

let s1 = Symbol('s1'); // => Symbol(s1)
let s2 = Symbol('s2'); // => Symbol(s2)
let s3 = Symbol('s1'); // => Symbol(s1)
Copy the code

At this time, we have to ask the curious baby, plus the description, the two Symbol values become the same.

s1 == s3 // => false
s1 === s3 // => false
Copy the code

Either == or === returns false, indicating that:

The argument to the Symbol function only represents a description of the current Symbol value, so the return value of the Symbol function with the same argument is not equal.

Type conversion

The Symbol value cannot be evaluated with other types of values and will report an error.

let s = Symbol('s');
s + ' is a Symbol! ' // => index.js:13 Uncaught TypeError: Cannot convert a Symbol value to a string
Copy the code

The Symbol value can be explicitly converted to a string.

let s = Symbol('s');
s.toString(); // => Symbol(s)
s.toString() + ' is a Symbol! ' // => Symbol(s) is a Symbol!
Copy the code

You can see that you can now add to the string.

The Symbol value can also be converted to a Boolean value, but not to a value.

let s = Symbol(a);Boolean(s); // => true! s// => false

Number(s); // => TypeError: Cannot convert a Symbol value to a number
Number(s) + 2; // => TypeError: Cannot convert a Symbol value to a number
Copy the code
  • The description added to Symbol above can only be obtained by an explicit toString() conversion, which is inconvenient

ES2019 provides an instance attribute, Description, that returns the description of Symbol directly.

let s = Symbol('this is a Symbol');
s.description // => this is a Symbol
Copy the code

Symbol usage

The Symbol value can be used as an identifier for the property name of the object.

I use a string as the attribute name, which is fast and convenient. Why do we use Symbol?

This question asks of good, a lot of study not careful (may have me only one) of children’s shoes have such question!

Let’s look at the introduction of Symbol:

ES6 introduces a new primitive data type, Symbol, that represents unique values.

Yes, unique. Have you ever encountered similar variable names in development and struggled to distinguish them? Are you afraid of overwriting, or being overwritten by, the name of a variable you added to an object written by another colleague? You need a Symbol value to renew your life (+ 1s).

Used as an attribute name

let s = Symbol(a);// The first way
let obj = {
    [s]: 'hello Symbol'
}

// The second way
let obj = {};
obj[s] = 'hello Symbol'

// The third way
let obj = {};
Object.defineProperty(obj,s,{value:'hello Symbol'})

// The result of the above three ways is
obj[s]; // => hello Symbol
Copy the code

Pay attention to

  • The Symbol value is the attribute name and cannot be read using the dot operator
  • When using the Symbol value as the attribute name inside an object, it must be placed in square brackets

Traversal as an attribute name

Symbol is the attribute name. When traversing the object, the attribute does not appear in the for… In, for… Of loop, will not be the Object. The keys (), Object, getOwnPropertyNames (), JSON. The stringify () returns.

For dafa cannot be traversed? Is that a private property? The answer is: NO, Object provides a Object. The getOwnPropertySymbols () method is used to retrieve objects within all Symbol attribute names, returns an array

Example: Eliminate magic strings

Eliminate magic string

Symbol.for()

Sometimes, we want to reuse the same Symbol value, and the symbol.for () method can do this.

let s1 = Symbol.for('s');
let s2 = Symbol.for('s');
s1 === s2; // => true
Copy the code

What is the difference between Symbol and symbol. for?

The former will be registered in the global environment for search, 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.

The end of the interview

The interview will be over by this time

But I have a feeling things may not be as simple as they seem

The built-in Symbol value

Take a look back at the end of Ruanda’s tutorial:

In addition to defining the Symbol values you use, ES6 provides 11 built-in Symbol values that point to methods used within the language.

Symbol.hasInstance

Object that points to an internal method. This method is called when another object uses the instanceof operator to determine whether it is an instanceof that object.

function fn(){}let ins = new fn();
ins instanceof fn; // => true
fn[Symbol.hasInstance](ins); // => true
Copy the code

Symbol.isConcatSpreadable

Object Symbol. IsConcatSpreadable attribute is a Boolean value, said that the object is used to Array. The prototype. The concat (), whether can be expanded.

let arr1 = ['a'.'b'];
let arr2 = ['c'.'d'];
arr1.concat(arr2); // => ['a','b','c','d']

arr2[Symbol.isConcatSpreadable] = false;
arr1.concat(arr2); // => ['a','b',['c','d']]
Copy the code

Symbol. Species, Symbol. Match, Symbol. Relpace, Symbol. Search, Symbol. Split…..

These za also don’t know what use, I also don’t understand, etc later have leisure time to go to study ~