Recently, I am reading the book deep ECMAScript6. I plan to talk about what I have learned, used and understood. I will basically follow the order of the book, which will be divided into three or four chapters. I will not write all of them. I will only choose some commonly used ones or ones that I think are more interesting.

Block-level scoped binding (let, const)

Why introduce block-level scopes

Prior to ES6, there was no concept of block-level scope in JavaScript, only global scope and block-level scope. That is, declaring a variable with the same name as the external variable in a block-level scope overwrites the external variable. Without block-level scope, there are two main problems.

  1. Block-level internal scope variable leakage
    var i = 1;
    console.log(i)                  // 1
    for(var i =0; i<10; i++){ console.log(i); / / 0... 9 } console.log(i) // 10Copy the code
  1. The function created in the loop retains the same variable references
    var funcs = [];
    
    for(var i = 0; i < 10; i++){ funcs.push(function (){
            console.log(i);
        });
    }
    
    funcs.forEach(function(func){ func(); // output 10 times the number 10});Copy the code

Both of the above problems are caused by the lack of block-level scopes, but ES6 has changed to introduce block-level scopes.

Let the statement

The use of the let declaration

Basically the same as VAR, but its life cycle is inside the block-level scope and disappears once out of the block-level scope. You cannot declare variables with the same name twice

The sample

Basic usage

    var i = 0;
    if(true) {leti = 100000; } console.log(i); / / 0Copy the code

Let declaration in loop

    var i = 1;
    console.log(i)                  // 1
    for(leti =0; i<10; i++){ console.log(i); / / 0... 9 } console.log(i) // 1Copy the code
Operation mechanism

In fact, each time the LET is created, it creates a new variable and initializes it with the value of the variable of the same name from the previous iteration. In short, let creates a copy of the value each time, rather than modifying the referenced value as var does.

When the for loop is first executed, it creates a new variable I (to create a chunk of memory), assigns 0 to the variable, and proceeds with the following statement; On the second execution, a new variable I is created (creating a new region of memory), and the new value of I is assigned to the new value of I, and the following statement continues. The cycle repeats until the conditions for the cycle are not met.

Const statement

The use of const declarations

The use of let is basically the same, but it cannot be changed once defined. Of course, if you’re using a reference, you can change the value inside the reference, but you can’t change the binding to the reference. And the const declaration must be initialized or an error will be reported.

The sample

The basic grammar

const name; // error, uninitialized const maxItems = 30; maxItems = 100; // Error, cannot change bindingCopy the code

Const declaration in a loop

var funcs = []; // An error is reported after an iterationfor(const i =0; i<10; i++){ funcs.push(function(){
            console.log(i);
        });
    }
Copy the code

And the reason why I got an error here is because the variable I is declared constant by const, and when we iterate to I ++, this statement wants to change the value of constant I, so it gets an error. And the magic part, let’s look at the following example

    var funcs = [];
    person = {
      name : 'Godfrey',
      age : 20,
      sex : 'male'
    };
    
    for(const key in person){
        funcs.push(function(){
            console.log(key);
        });
    }
    
    funcs.forEach(function(func){ func(); // print name, age, sex});Copy the code

You’ll notice that this is a bit different from what we said above. Const is a constant and cannot be modified. Why can be executed correctly in this for-in loop. Don’t worry, in for-in and for-of loops, each iteration does not modify the existing binding, but instead creates a new binding, just as I described in the let loop above. That is, in some cases, const and let behave exactly the same.

Temporary Dead Zones (TDZ)

With the introduction of let and const declarations came the concept of temporary dead zones.

Simply put, temporary death means that a variable cannot be used until it is initialized. Let’s look at an example

    if(true){ console.log(typeof a); // Reference errorlet a = 1;
    }
Copy the code

If a variable is declared by var, the JavaScript engine promotes the variable. If a variable is declared by let or const, the JavaScript engine adds a “temporary dead zone”.

Tips: Access lets declared outside of the block-level scope, const variables with the same name do not report errors, that is, “temporary dead zones” only apply to the current block-level scope.

Strings and regular expressions

ES6 introduces some new methods and features with respect to strings. These include strings, regular expressions, and template literals

New string features

  • Better Unicode support
  • CodePointAt () method — The Unicode-16 version of charCodeAt() takes the position of an encoding unit as an argument instead of the position of the string, and returns code points corresponding to the given position of the string.
    let test = "𠮷 a."
    
    console.log(test.charCodeAt(0));    // 55362
    console.log(test.charCodeAt(1))     // 57271
    console.log(test.charCodeAt(2))     // 97
    
    console.log(test.codePointAt(0));    // 134071
    console.log(test.codePointAt(1))     // 57271
    console.log(test.codePointAt(2))     // 97
    
Copy the code
CharCodeAt (0) returns the first encoding unit at position 0, which is usually not what we want, while codePointAt(0) returns the full encoding unit for the first word.Copy the code
  • The string.fromCodePoint () method is used to generate a character based on the specified code point
console.log(String.fromCodePoint(134071)); / / 𠮷Copy the code
  • The normalize() method is a method that you can ignore for the time being, mainly for internationalization

New string methods

  • Includes () returns true if the specified text is detected in the string, false otherwise.
  • StartsWith () returns true if the specified text is detected at the start of the character stream, false otherwise.
  • EndsWith () returns true if the specified text is detected at the end of the string, false otherwise.
    let test = 'Hello world';
    
    console.log(test.includes("Hello"));        // true
    console.log(test.includes("a"));            // false
    console.log(test.startsWith("Hello"));      // true
    console.log(test.startsWith("Hello", 4)); //false
    console.log(test.endsWith("d"));            // true
    console.log(test.startsWith("Hello"));      // false
    console.log(test.endsWith("o", 8)); //true      
    

Copy the code

All three methods take two arguments. The first is the text content to detect, and the second is the index of the location searched in the first place. Both includes and startsWith start the search at the index position, while endsWith starts the match at the index position minus the string length.

This is the main new method for ES6 strings.

New regular expression features

ES6 also enhances regular expressions to better satisfy string manipulation in development.

  • U modifier When the U modifier is added to a regular expression, the operation of the regular expression changes from encoding units to character modes.
    let test = "𠮷";
    
    console.log(text.length);                   // 2
    console.log(/^.$/.test(test));              // false
    console.log(/^.$/u.test(test));             // true
Copy the code
  • Y modifier The Y modifier affects the lastIndex attribute in the regular expression search. If it is used, the match starts at latIndex. If the match fails at the specified location, the match continues.
    var text = "kidd1 kidd2 kidd3"; var pattern = /kidd\d\s? /; var result = pattern.exec(text); var globalPattern = /kidd\d\s? /g; var globalResult = globalPattern.exec(text); var stickyPattern = /kidd\d\s? /y; var stickReslut = stickyPattern.exec(text); console.log(result[0]); //"kidd1 "
    console.log(globalResult[0]);               // "kidd1 "
    console.log(stickReslut[0]);                // "kidd1 "
    
    pattern.lastIndex = 1;
    globalPattern.lastIndex = 1;
    stickyPattern.lastIndex = 1;
    
    result = pattern.exec(text);
    globalResult = globalPattern.exec(text);
    stickReslut = stickyPattern.exec(text);
    
    console.log(result[0]);                     // "kidd1 "
    console.log(globalResult[0]);               // "kidd2 "
    console.log(stickReslut[0]);                // null
    
Copy the code

tips:

  1. The y modifier only works on string objects, not string methods.
  2. Also, when using the ^ character, only the beginning of the string is matched to the first line of the multi-line pattern. When lastIndex is 0, that’s fine, just like a regular regular expression. But when lastIndex is not zero, the correct result will never be matched
  • Before ES6, there was a minor bug in using constructors to create regular expressions. The first argument was a regular expression, and the second argument could add some modifier to the regular expression. However, when the first argument is a reference to another regular expression and the second argument is passed in, ES5 will report an error. Now ES6 fixes this problem
Var regex1 = /ab/g; // An error will be thrown in ES5. But in ES6 it's normal. var regex2 = new Regex2(regex1,"i");
    
    console.log(regex1.toString());         // "/ab/g"
    console.log(regex2.toString());         // "/ab/i"

Copy the code
  • ES6 also adds a new attribute for regular expression objects, flags, to help us access modifiers in regular expressions more quickly. Calling it through a regular expression object, she returns all the modifiers for that regular expression.
    var regex = /ab/g;
    
    console.log(regex.flags);               // "g"
Copy the code

Template literals

This is a new syntax introduced in ES6. The main purpose is to address string multi-line patterns, placeholders, and to provide more powerful string manipulation.

Basic grammar

Template literals are used in the same way as string literals, with backapostrophes (‘) instead of quotes (single or double). The most obvious feature is support for multi-line strings.

    var message = `123
    456
    789`;
    
    console.log(message);           //"123 // 456 // 789"
                                    
Copy the code

The above is the most basic use of template literals. It doesn’t seem to be particularly powerful, and ES5 can do exactly that, except that it requires manual stitching. Good! Here’s where template literals get really powerful (and really, really powerful depends on the application, since programming is more of an applied science).

String placeholder

The basic syntax for string placeholders is ${}, which can contain any JavaScript expression in the middle. String placeholders give you the ability to embed a “representation” in a string, and it calculates the result. So without further ado, let’s do a simple example.

    let a = 123,
        b = 456;
    message = `Sum is ${a + b}`;
    
    console.log(message);           // "Sum is 579";

Copy the code

String placeholders are also nested.

The label template

First we need to explain what a label is. A label is a string annotated before the first backapostrophe (‘) of a template literal. Of course, this string does not need to be quoted. Of course, it doesn’t matter if the tag is just a string, but if it could be a reference to a function object, that would be very powerful. In this case, when we’re dealing with strings of the same type, it’s very convenient to add a tag directly before them.

    functiontag(literals,... substitutions){let result = "";
        
        for(leti = 0; i< substitutions.length; i++){ result += literals[i]; result += substitutions[i]; }; result += literals[literals.length-1];return result;
    }
    
    let a = 123,
        b = 456,
        message = tag `Sum is ${a+b}`;
    
    console.log(message);           // "Sum is 579";
Copy the code

Above we have the tag that emulates the default line of the template literal. We can see that the function has two arguments, both of which are arrays.

  • The literals literals parameter is actually an array, and you can think of it as passing in all the strings except the placeholders, but splitting those strings by placeholders creates an array for literals. Another point is that if the first part of the template literal is a placeholder, the first value of the literals array is an empty string. This ensures that literals are always one more than substitutions.
  • If there is an array for strings, then substitutions must have a place for string placeholders. That is, the substitutions array. It holds the value of the evaluated expression.

Above are the additions and modifications to ES6 for strings and regular expressions.

The content of this article is all the knowledge I learned from the books and added some of my own understanding. There may be mistakes. If you see them, please point them out. If you do not understand the content of the article, you can leave a comment below, I will be more detailed explanation.