Var, Let, Const

The var statement
  • Variable promotion mechanismUsing the javaScript engine, when the code is precompiled, the javaScript engine automatically puts all the code insidevarStatements declared by keywords are promoted to the top of the current scope.

Let’s look at

 function person1(status) { 
             if (status) { 
                var value = "Cola" 
             } else { 
             console.log(value) // undefined 
             } 
             console.log(value) // undefined 
    } 

 function person2(status) { 
         var value; 
         if (status) { 
             value = "Cola" 
         } else { 
         console.log(value) // undefined 
         } 
         console.log(value) // undefined 
} 
Copy the code

The code that passes through the variable promotion mechanism person1 becomes Person2.

Therefore, Escript6 brings block-level declarations for us.

  • Only variables declared under the current function are valid;
  • Valid within code blocks and {} parentheses;
Let the statement
  • Block-level scope, all statements outside the block cannot access ‘
  • Let has no variable promotion;

Let’s look at

Function person3(status) {if (status) {let value = "Cola"} else {console.log(value)} The console. The log (value) / / an error} -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- / / block-level scope the console. The log (value) / / an error value = "Cola"Copy the code

ECMAscript6 also provides a const keyword declaration, which is a constant. Constants are values that cannot be changed once they are defined. One other thing to note is that constant definitions must initialize values. If they are not initialized, an error is reported. Let’s look at const.

Const statement
  • Block-level scope, all statements outside the block access, no variable promotion;

  • A value defined by const must have an initial value and cannot be modified;

  • Const declarations can modify values, but cannot override the whole object.

    const age; Const age = 14; Age = 16; Const person = {name: "Cola", age: 23} person.age = 18 person = {Copy the code
Why do let and const have no variable promotion?
※ Temporary dead zone

The error is reported because variable statements defined and initialized with let are not executed. The value is still in what JavaScript calls a temporal dead zone, or TDZ for short.

Let’s take a look at how TDZ works. When the JavaScript engine scans code and finds variable declarations, it will push them to the top of the current scope if it encounters var. If it encounters let or const, it will put the declarations in TDZ. The variable in TDZ will be removed only after it has been executed, and then the normal method can be used. This mechanism only works in the current scope.

Let’s see:

    console.log(value) // 'undefined'
    if (true) { 
        let value = "Cola" 
    }
Copy the code

This is what we call a temporary dead zone

Var let const

Variables declared by var in the global scope have a behavior that is attached to the Window object. It creates a new global variable as a property of the global object. This behavior may override a property of the Window object, whereas variables declared by let and const do not.

Let’s read on: Font-family: heliostat; font-family: heliostat

    var value1 = "Cola1"
    let value2 = "Cola11"
    const value3 = "Cola111"
    console.log(window.value1) // Cola1
    console.log(window.value2) // undefined
    console.log(window.value3) // undefined
Copy the code

Arrow function

Note the usage scenarios:

  • Methods cannot define constructors;
  • Can’t call arguments;
  • This will follow the parent, which does not point to the window by default;
  • You can call the call() method;
  • Cannot be called by the new keyword;
  • No prototype;
  • Suitable for callbacks unrelated to this (timers, array methods, etc.);
  • Not suitable for callbacks related to this (object methods, event callbacks);

Basic writing:

//ES6 adds arrow functions: let func = value => value; Let func = (value, num) => value * num; Let func = (value, num) => ({total: value * num}); Var result = func({value: 10, num: {value: 10, num: {total: value * num}); 10 }) console.log(result); / / {total: 100} / / since the executive function (function () {the console. The log (1)}) () () (= > {the console. The log (1)}) ()Copy the code

Extended operator

  • Extension operators (… A) Allows an expression to be extended where multiple arguments (for function calls) or elements (for array literals) or variables (for deconstructing assignments) are expected.

Let’s get straight to the use of this thing:

Array uses:

Var a = [1, 2]; Var b = [0... a, 3] / / array divided var [a, b]... = [0, 1, 2]; Console. log(b) //[1, 2] // copy array var a = [1, 2]; var b = [...a];Copy the code

Object using:

let { x, y, ... z } = { x: 1, y: 2, a: 3, b: 4 }; console.log(z) // {a: 3, b: 4}Copy the code

The above simple introduction, are often used.

Symbol attribute

ES6 added the seventh primitive data type Symbol, a brief introduction to its use methods and use scenarios

⭐ Note: we do not use the new operator when creating values through the Symbol method. The reason is that the result of the new instantiation is an object object, not the Symbol of the original type, and a unique value is defined.

Create type Symbol value:

const a = Symbol(); console.log(typeof s); // 'symbol' // const a = symbol ('111'); // unique value const a = Symbol('111'); const b = Symbol('111'); console.log(a === b); // falseCopy the code

Common methods:

Symbol. For: Checks if a Symbol value created using this method with the same argument already exists in the context, returns the value if it exists, and creates a new value if it does not.

    const a1 = Symbol.for('111');
    const q2 = Symbol.for('111');

    console.log(a1 === q2); // true
Copy the code

Symbol.keyFor: Returns a key for the Symbol value created using the symbol. for method.

   let A = Symbol.for('uid');
    console.log(Symbol.keyFor(A));    // "uid"

    let B = Symbol.for('uid');
    console.log(Symbol.keyFor(B));   // "uid"

    let C = Symbol('uid');
    console.log(Symbol.keyFor(C));   // undefined
Copy the code

A few of them are listed briefly above, and others can be seen in official documents. 🤭 es6.ruanyifeng.com/?search=Sym…

The Iterator (Iterator)

Get a feel for iterators

  • IteratorAn interface designed to provide a unified data access mechanism for different data structures. Or you could say thatIteratorThe main interface isfor ofServe, servefor... ofConsumption.

Let’s look at the basic use of iterators:

Const a = ['a','b','c'] let arr = a[symbol.iterator]() // Call object next method console.log(iterator.next()) //{value:'a',done:false} console.log(iterator.next()) //{value:'b',done:false} console.log(iterator.next()) //{value:'c',done:false} console.log(iterator.next()) //{value:undefined,done:true}Copy the code

The working principle of

  • Create a pointer object that points to the start of the current data structure.
  • The first time the object’s next method is called, the pointer automatically points to the first member of the data structure;
  • The next method is called repeatedly, and the pointer automatically moves backwards until it points to the last member;
  • Each call to the next method returns an object containing the value and done attributes;

Implementation iterator

Now let’s do an iterator: Font-Family: inherit; font-family: inherit

Let obj = {name: '3 ', array: [ 'eqebj', 'daduo', 'grguy', 'rgrmo' ], [Symbol.iterator]() { let index = 0 let _this = this let _done = false return { next: function () { if (index < _this.array.length) { const result = {value: _this.array[index], done: _done} index++ return result } else { return {value: undefined, done: ! For (let arr of obj) {console.log(arr)}Copy the code

Moving on, what else can our iterator (Interator) do — —

Deconstruction assignment

Let obj = {name: '3 ', array: [ 'eqebj', 'daduo', 'grguy', 'rgrmo' ], [Symbol.iterator]() { let index = 0 let _this = this let _done = false return { next: function () { if (index < _this.array.length) { const result = {value: _this.array[index], done: _done} index++ return result } else { return {value: undefined, done: ! _done}}}}}} // Let [a, b, c] = obj console.log(a) //eqebj console.log(b) //daduo console.log(c) //grguyCopy the code

Ok, at present these kinds are more commonly used, we should remember oh! 😊 — secretly tell you the interview will add extra points oh! (low ˇ ∀ ˇ “)

Ouch! I just remembered a little bit, for… In and for… The difference between:

  • For in loop — key name
  • For of loop — key value

Generator (generator)

Here we go again to our generator, which continues with 💪💪💪

Concept:

  • Generator functions are an asynchronous programming solution provided by ES6. The syntax behavior of Generator functions is completely different from traditional functions.
  • Syntactically, the Generator function is a state machine that encapsulates multiple internal states.
  • The Generator function is also an iterator object Generator in addition to a state machine.
  • Paused functions (lazy evaluation), yield paused, and the next method started. Yield is returned each time;

Main function: To solve the problem of callback region — (asynchronous)

Now let’s see how to use

The basic use

The Generator functions are executed pieceally, calling the next method. The internal logic of the function starts execution, stops when the yield expression is encountered, and returns {value: yield /undefined, done: False /true}, calling the next method again will start at yield from the last stop until the end.

    function* fun() {
      yield '111';
      yield '222';
      return '333';
    }
    var h = fun();
    h.next()// { value: '111', done: false }
    h.next()// { value: '222', done: false }
    h.next()// { value: '333', done: true }
    h.next()// { value: undefined, done: true }
Copy the code

Next Pass parameters

The yield expression itself returns no value, or always returns undefined. The next method can take an argument that is treated as the return value of the previous yield expression.

Function * fun() {console.log(' start execution ') let result = yield '111' console.log(result) yield '222'} let M = fun() m.next () // 11 // {value: "222", done: false}Copy the code

Relationship to iterators

Since a Generator function is an iterator Generator function, you can assign Generator to the Symbol. Iterator property of an object so that the object has an Iterator interface.

    let obj = { 
        name: 'Cola',
        age: 19 
    }
    
    obj[Symbol.iterator] = function* fun() {
      yield 1;
      yield 2;
      yield 3;
    };
    
    for (let i of obj) {
      console.log(i)  // 1 2 3
    }
Copy the code

The Generator function assigns the Symbol. Iterator property, thus giving the obj object an iterator interface that can be iterated for of.

Promise the asynchronous

The Promise constructor takes one argument: the function, and this function takes two arguments:

  • Resolve: Callback function after asynchronous operation is successfully executed
  • Reject: Callback function when an asynchronous operation fails

Know the promise

Let p = new Promise((resolve, reject) => {// async callback setTimeout(() => {console.log(' done ')); Resolve (' I am success!! '); }, 2000); });Copy the code

Promises are designed to solve two problems:

  • Callback hell, code is difficult to maintain, often the output of the first function is the input of the second function;
  • Promises can support multiple concurrent requests, retrieving data from concurrent requests;
  • This promise solves the problem of asynchrony, not asynchrony by itself;

Promise encapsulates ajax requests

As we apply every bit of this to the real world, let’s look at promise encapsulating asynchronous Ajax.

Const p = new Promise((resolve, reject) => {// create object let XML = new XMLHttpRequest() // initialize xml.open('get', Xml.onreadystatechange = function () {if (xml.readyState === 4) { If (xml.status >= 200 && xml.status < 300) {// Resolve (xml.response)} else {// Reject (xml.status)}}}})  p.then(function (value) { console.log(value) }, function (reason) { console.error(reason) })Copy the code

Above is we often use the asynchronous send request, we are free to contact…

Chain operation of THEN

When multiple requests are requested together or multiple files are requested at once, it is possible to create callback hell using normal methods. Therefore, you can prevent multiple file callback hell by using chain operations.

Here’s an example:

    const fs = require('fs')
    const p = new Promise((resolve, reject) => {
        fs.readFile('./data1.md', (err, data) => {
            if (true) resolve(data)
            else reject(err)
        })
    })

    p.then(value => {
        return new Promise((resolve, reject) => {
            fs.readFile('./data2.md', (err, data) => {
                if (true) resolve([value, data])
                else reject(err)
            })
        })
    }, reason => {
        console.error(reason)
    }).then(value => {
        return new Promise((resolve, reject) => {
            fs.readFile('./data3.md', (err, data) => {
                if (true) {
                    value.push(data)
                    resolve(value)
                } else {
                    reject(err)
                }
            })
        })
    }, reason => {
        console.error(reason)
    }).then(value => {
        console.log(value.toString())
    }, reason => {
        console.error(reason)
    })
Copy the code

This example uses the nodeJS configuration, you can try to match it when applying!! All, promise. Race, promise. Any, promise.

This knowledge point many 🤭, see here everyone should be tired, pay attention to rest ha, the next chapter then come out, refueling oh! The hard work of the programmed apes.