The introduction

Great oaks from little acorns grow. If you want to practice this skill, you must first lay down the basic skills.

Before we look at the new variable types in ES6, we need to know that JavaScript had six basic data types before ES6: Null, Undefined, Number, String, Boolean, and Object. In ES6, a seventh data type is added: Symbol. The above seven data types are divided into the following types:

Basic types: Undefined, Null, Boolean, String, Number, these five types of variables are directly stored in the stack memory, operation or access to the actual value.

Reference type: Object. A variable of type Object is a type of data that stores the address value pointing to heap memory in stack memory. (The stack will be covered in a later article.)

There are many articles on the web that explain basic types and reference types, but I won’t repeat them here to avoid getting too long.

Symbol type:

Symbol is a function that returns only the value of the Symbol type.

Using new before Symbol is not allowed. Values of type Symbol can be created by calling the Symbol function directly

let symbol = Symbol(a); symbol;//Symbol()
typeof symbol;  //symbol
let symbol1 = new Symbol(a);//Uncaught TypeError: Symbol is not a constructor
Copy the code

When the Symbol function is called, it accepts an argument that is converted to a string by the toString method as a description of the Symbol value. The argument passed in cannot be considered a value of type Symbol

let testStr = 'this is a string',
    testObj = {obj: 'this is a object'},
    testArr = ['this'.'is'.'a'.'array'],
    testFn = (a)= > {
        console.log('this is a function');
    },
    testSym = Symbol('this is a symbol'),
    symbolStr = Symbol(testStr),            //Symbol(this is a string)
    symbolObj = Symbol(testObj),            //Symbol([object Object])
    symnolArr = Symbol(testArr),            //Symbol([object Object])
    symbolFn = Symbol(testFn),              //Symbol(() => {console.log('this is a function'); })
    symbolSym = Symbol(testSym);            //Uncaught TypeError: Cannot convert a Symbol value to a string
Copy the code

The value generated after the Symbol function call is unique

let symbol1 = Symbol('test'),
    symbol2 = Symbol('test');
symbol1 == symbol2;         //false
symbol1 === symbol2;        //false
Copy the code

The value of Symbol cannot be computed or converted implicitly with other types of values, otherwise an error will be reported. But it can be explicitly converted to a string using the toString method.

let symbol = Symbol('this is symbol'),
    str = 'this is string',
    num = 2,
    symStr = symbol.toString();
    
let newStr = symbol + str;          //Uncaught TypeError: Cannot convert a Symbol value to a string
let newNum = Symbol + num;          //Uncaught TypeError: Cannot convert a Symbol value to a number
symStr;                             // Symbol(this is symbol)
Copy the code

The uniqueness of the Symbol value, used in the properties of Object, ensures that no properties of the same name will occur

let symbol = Symbol('this is symbol'),
    symbol1 = Symbol('this is symbol');
let obj = {
    [symbol]: 'this is a',
    [symbol1]: 'this is b'
};
obj;            //{Symbol(this is symbol): "this is a", Symbol(this is symbol): "this is b"}

let str = 'test',
    str1 = 'test',
    obj = {};
obj[str] = 'Testing properties not named for symbol type';
obj;            //{test: "Test non-symbol named attributes "}
obj[str1] = 'Test again for properties not named with type symbol';
obj;            //{test: "Test again for attributes not named with type symbol "}
Copy the code

Symbol name property can be through the Object. GetOwnPropertySymbols acquisition

let symbol = Symbol('this is symbol'),
    symbol1 = Symbol('this is symbol');
let symbolObj = {
    [symbol]: 'this is a',
    [symbol1]: 'this is b',}Object.getOwnPropertySymbols(symbolObj);    //[Symbol(this is symbol), Symbol('this is symbol')]
Copy the code

Properties named with Symbol values do not appear in object. keys, for… in… Through Object. GetOwnPropertyNames (), JSON. The stringify () also can’t get the return value. But that property is public, not private.

let symbol = Symbol('this is symbol'),
    symbol1 = Symbol('this is symbol');
let obj = {
    [symbol]: 'this is a',
    [symbol1]: 'this is b'.d: 'test'
};
for(key in obj){
    console.log(key);               // d
}
Object.keys(obj);                   // ['d']
Object.getOwnPropertyNames(obj);    // ['d']
JSON.stringify(obj);                //{d:'test'}

// The attribute key and value defined by the Symbol value can still be accessed
let symKeys = Object.getOwnPropertySymbols(obj);  
symKeys;                    //[Symbol(this is symbol), Symbol(this is symbol)]
symKeys[0];                 //Symbol(this is symbol)
obj[symKeys[0]].//this is a
Copy the code

For (‘ XXX ‘) is used to obtain a Symbol value generated with ‘XXX’ as an input parameter. If no Symbol value generated with ‘XXX’ as an input parameter exists, a Symbol value generated with ‘XXX’ as an input parameter is automatically created.

let symbol = Symbol('this is symbol'),
    symbol1 = Symbol.for('this is symbol'),
    symbol2 = Symbol.for('this is symbol');
symbol === symbol1      //false
symbol === symbol2      //false
symbol1 === symbol2     //true
Copy the code

12. The Symbol. KeyFor method returns a modifier of a “registered” Symbol type value.

Values created through Symbol can be registered and unregistered. What is registered? in

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

var s2 = Symbol("foo");
console.log(Symbol.keyFor(s2) ); // undefined
Copy the code

Here are some MDN attributes about Symbol, because I feel that the probability of daily use is relatively low, so I don’t want to describe some of my own understanding, interested friends can go to seeDeveloper.mozilla.org/zh-CN/docs/…


Summary of Symbol: In my opinion, the most practical use of Symbol is when the Symbol value is used for attribute naming. In some development cases, when traversing an Object, it is hoped that some attributes will not be traversed by for in or object.keys. Instead of doing if or switch cases, use Symbol to define attribute names instead. In the process of attribute naming and assignment in ES5, multi-party development may cause some attribute names to be renamed and value overwritten. Using Symbol for “semi-private attribute” attributes is a good choice.


Iterator – an Iterator

ES6 adds two new data structure types (Map and Set) to the original data structure types (Array and Object). We can use these structure types in the form of free combination to achieve the desired data structure. This requires a unified interface mechanism that we can call to handle different data structures — iterators.

In ES6, the iterated “object” is considered “traversable” as long as it has an iterable protocol, that is, the System. Iterator property.

In ES6, there are three types of data structures that have the Iterator interface natively: arrays, some array-like objects (such as strings, array-like objects), and Set and Map structured data.

The iterator protocol defines a standard way to produce a finite or infinite sequence of values. Each iteration begins with a call to the [symbol.iterator]() method on the iterated data set object, which returns the iterator property of a Symbol object. This property holds the Next method that executes the iterated object and returns an object. Here is a snippet of code that mimics the Next method

function Iterator(arr){
    let nextIndex = 0;
    return {
        next: function(){
            return nextIndex < arr.length ? {value: arr[nextIndex++], done: false}, {value: undefined.done: true}; },Symbol.iterator]: function() { return this}}}let example = Iterator(['a'.'b']);

example.next()      // {value: "a", done: false}
example.next()      // {value: "b", done: false}
example.next()      // {value: undefined, done: true} // Traversal ends
Copy the code

The returned object must contain the following two attributes

{
    done,       Return true if the iteration is complete, false otherwise, and continue if false
    value       // Return undefined at the end of iteration, otherwise return the current member's value
}
Copy the code

In some cases, JS will be called by defaultSymbol.iterator(the Iterator interface)

  1. Extended operator

    Extended operators (…) The iterator interface is called by default.

  2. Deconstruction assignment

    The symbol. iterator method is called by default when destructuring arrays and Set structures.

  3. yield*

    Yield * is followed by a traversable structure that calls the iterator interface of that structure.

  4. for… of

    The for… The of loop calls the iterator interface to process the data.

  5. Array.from()

    In array.form (), the data is iterated over, and the iterator interface is called to return the data

  6. Other cases include Map(), Set(), WeakMap(), WeakSet() (such as new Map([[‘a’,1],[‘b’,2]])), promise.all (), promise.race ().


By the way:

In ES6, objects with the System. Iterator attribute can pass for… Of traverses

let arr = ['1'.'2'.'3'];
arr.pro = 'test';
for (let i in arr) {
  console.log(arr[i]);          //1 2 3 test
}
for(let i of arr) {
    console.log(arr[i]);        //1  2  3
}
Copy the code

for… Compared with forEach, for… ForEach loops can’t break out of a loop with a break, continue, or return, while for… You can, for… The in loop is designed to iterate over objects that contain key-value pairs and is not so array friendly, whereas the for… The output value of the “of” traversal ends by default after the output data.


Summary of Iterator: Iterator serves as a unified interface mechanism for us to call different data structures, so that we can traverse the collection in the same way, regardless of the internal implementation of the collection. If the form of the data changes, as long as the System. Iterator property exists inside the data. The traversal code can then be used without modification. At the same time, it serves for… Of cycle, for… In addition, of can effectively avoid the previous data set only through forEach, for.. Part of the problem encountered in traversal.

The above.

If there are mistakes in the content of the article, welcome to point out the exchange and mutual progress