"ES6" - learning notes

Posted by Rodis on Fri, 31 Dec 2021 21:15:42 +0100

Compare the scope of the var and let keywords

When a variable is declared with the var keyword, it is declared globally. If it is declared inside a function, it is declared locally.

The let keyword behaves similarly, but has some additional functionality. When you use the let keyword to declare a variable in a code block, statement, or expression, its scope is limited to that code block, statement, or expression.

For example:

var numArray = [];
for (var i = 0; i < 3; i++) {
  numArray.push(i);
}
console.log(numArray);
console.log(i);

Here the console will display the values [0, 1, 2] and 3.

Using the var keyword, i is globally declared. So when i + + is executed, it updates global variables. This code is similar to the following:

var numArray = [];
var i;
for (i = 0; i < 3; i++) {
  numArray.push(i);
}
console.log(numArray);
console.log(i);

Here the console will display the values [0, 1, 2] and 3.

If you create a function, store it and use it later in the for loop using the i variable. This may cause problems. This is because the stored function will always reference the value of the updated global i variable.

var printNumTwo;
for (var i = 0; i < 3; i++) {
  if (i === 2) {
    printNumTwo = function() {
      return i;
    };
  }
}
console.log(printNumTwo());

The console will display the value 3 here.

As you can see, printnumtwo () prints 3 instead of 2. This is because the value assigned to i has been updated, and printNumTwo() returns the global i instead of the value of i when the function was created in the for loop. let keyword will not appear this phenomenon:

let printNumTwo;
for (let i = 0; i < 3; i++) {
  if (i === 2) {
    printNumTwo = function() {
      return i;
    };
  }
}
console.log(printNumTwo());
console.log(i);

Here, the console will display a value of 2 and an error prompt i is not defined.

i is not defined because it is not declared globally. It is only declared in a for loop statement. printNumTwo() returned the correct value because the let keyword created three different i variables with unique values (0, 1, and 2) in the loop statement.

Object.freeze prevent object changes

const declarations do not really protect data from being changed. To ensure that the data is not changed, JavaScript provides a function object freeze.

Any attempt to change the object will be rejected and an error will be thrown if the script runs in strict mode.

let obj = {
    name:"FreeCodeCamp",
    review:"Awesome"
};
Object.freeze(obj);
obj.review = "bad";
obj.name = "Test";
console.log(obj); 

obj.review and obj The assignment of newprop will cause an error, because our editor runs in strict mode by default, and the console will display the value {name: "FreeCodeCamp", review: "Awesome"}.

Arrow function

In JavaScript and TypeScript, we often encounter situations where we don't need to name a function, especially when we need to pass a function as a parameter to another function. At this point, we will create an anonymous function. Because these functions are not reused elsewhere, we don't need to name them.

In this case, we usually use the following syntax:

const myFunc = function() {
    const myVar = "value";
    return myVar;
}

ES6 provides syntax sugar for other ways to write anonymous functions. You can use the arrow function:

const myFunc = () => {
  const myVar = "value";
  return myVar;
}

The arrow function allows you to omit the return keyword and the outer braces when you don't need the function body and only return a value. In this way, a simple function can be simplified into a single line statement.

const myFunc = () => "value";

This code returns the string value by default.

Arrow function with parameters

Like a normal function, you can also pass parameters to the arrow function.

JavaScript:

const doubler = (item) => item * 2;
doubler(4);

TypeScript:

const doubler = (item: number) => item * 2;
doubler(4);

doubler(4) will return 8.

If the arrow function has only one parameter, you can omit the parentheses outside the parameter.

const doubler = item => item * 2;

Note: if type annotation is required in TypeScript, parentheses cannot be omitted. If parentheses are omitted, type annotation will not be performed. The default is any type

You can pass multiple parameters to an arrow function.

JavaScript:

const multiplier = (item, multi) => item * multi;
multiplier(4, 2);

TypeScript:

const multiplier = (item: number, multi: number) => item * multi;
multiplier(4, 2);

multiplier(4, 2) will return 8. Arrow function of parameter

Like a normal function, you can also pass parameters to the arrow function.

const doubler = (item) => item * 2;
doubler(4);

doubler(4) will return 8.

If the arrow function has only one parameter, you can omit the parentheses outside the parameter.

const doubler = item => item * 2;

You can pass multiple parameters to an arrow function.

const multiplier = (item, multi) => item * multi;
multiplier(4, 2);

multiplier(4, 2) will return 8.

Set the default parameters of the function

ES6 allows you to pass in default parameters to functions to build more flexible functions.

See the following code:

const greeting = (name = "Anonymous") => "Hello " + name;

console.log(greeting("John"));
console.log(greeting());

The console displays the strings Hello John and Hello Anonymous.

The default parameter will work when the parameter is not specified (the value is undefined). In the above example, the parameter name will use the default value Anonymous when it does not get a new value. You can also give default values to multiple parameters.

rest operator

ES6 introduces the rest operator for function parameters to help us create more flexible functions. The rest operator can be used to create a function with one variable to accept multiple parameters. These parameters are stored in an array that can be read inside the function.

See the following code:

function howMany(...args) {
  return "You have passed " + args.length + " arguments.";
}
console.log(howMany(0, 1, 2));
console.log(howMany("string", null, [1, 2, 3], { }));

The console displays the string You have passed 3 arguments And You have passed 4 arguments.

Using the rest parameter eliminates the need to view the args array, and allows us to use map(), filter(), and reduce() on the parameter array.

give an example:

/**
 *
 * @returns {*}
 * @param args
 */
const sum = (...args) => {
    return args.reduce((a, b) => a + b, 0);
}

console.log(sum(0, 1, 2))

spread operator expands an array item

ES6 introduces the expansion operator, which can expand arrays and expressions that require multiple parameters or elements.

The following ES5 code uses apply() to calculate the maximum value of the array:

var arr = [6, 89, 3, 45];
var maximus = Math.max.apply(null, arr);

The value of maximum is 89.

We have to use math Max.apply (null, ARR), because math Max (ARR) returns NaN. Math. In the max() function, you need to pass in a series of comma separated parameters, not an array. Expanding operators can improve the readability of the code and make the code easy to maintain.

const arr = [6, 89, 3, 45];
const maximus = Math.max(...arr);

The value of maximum should be 89.

... arr returns a decompressed array. That is, it expands the array. However, the expansion operator can only be used in function parameters or arrays. The following code will report an error:

const spreaded = ...arr;

Use deconstruction assignment to get the value of the object

Deconstruction assignment is a new syntax introduced by ES6 to extract values from arrays and objects and assign variables gracefully.

There are the following ES5 Codes:

const user = { name: 'John Doe', age: 34 };

const name = user.name;
const age = user.age;

The value of name should be the string John Doe, and the value of age should be the number 34.

The following is to use ES6 to deconstruct the assignment statement to achieve the same effect:

const { name, age } = user;

Similarly, the value of name should be the string John Doe, and the value of age should be the number 34.

Here, the name and age variables are automatically created and the values of the corresponding attributes of the user object are assigned to them. This method is much simpler.

You can extract as many or as few values as possible from the object.

Assign variables from objects using deconstruction assignment

You can assign a new variable name to the deconstructed value by placing the new variable name after the colon when assigning a value.

Take the object of the above example as an example:

const user = { name: 'John Doe', age: 34 };

This is an example of specifying a new variable name:

const { name: userName, age: userAge } = user;

You can understand this code as follows: get user Name, assign it to a new variable userName, and so on. The value of userName will be the string John Doe and the value of userAge will be the number 34.

Assign variables from nested objects using deconstruction assignment

Use objects similar to those in the previous example:

const user = {
  johnDoe: { 
    age: 34,
    email: 'johnDoe@freeCodeCamp.com'
  }
};

This is the property value of the deconstruction object assigned to a variable with the same name:

const { johnDoe: { age, email }} = user;

This is to assign the attribute value of the object to variables with different names:

const { johnDoe: { age: userAge, email: userEmail }} = user;

Assign variables from an array using deconstruction assignment

In ES6, deconstructing arrays can be as simple as deconstructing objects.

Unlike array deconstruction, array expansion will decompose all the contents of the array into a comma separated list. Therefore, you cannot choose which element to assign a value to a variable.

Deconstructing an array allows us to do this:

const [a, b] = [1, 2, 3, 4, 5, 6];
console.log(a, b);

The console will display the values of a and b as 1, 2.

The first value of the array is assigned to variable a and the second value of the array is assigned to variable b. We can even use comma separator in array deconstruction to obtain any desired value:

const [a, b,,, c] = [1, 2, 3, 4, 5, 6];
console.log(a, b, c);

The console will display the values of a, b, and c as 1, 2, and 5.

Use deconstruction assignment with rest operator to reallocate array elements

In some cases of deconstructing an array, we may want to put the remaining elements into another array.

The result of the following code is the same as using array prototype. Slice() is similar to:

const [a, b, ...arr] = [1, 2, 3, 4, 5, 7];
console.log(a, b);
console.log(arr);

The console will display 1, 2 and [3, 4, 5, 7].

Variables a and b receive the first and second values of the array, respectively. Then, due to the existence of the rest operator, arr obtains the values of the remaining elements of the original array. The rest operator works only on the last element of the array list. This means that you cannot use the rest operator to intercept the elements in the middle of the original array as sub arrays.

Use deconstruction assignment to pass an object as an argument to a function

In some cases, you can deconstruct the object directly in the parameters of the function.

See the following code:

const profileUpdate = (profileData) => {
  const { name, age, nationality, location } = profileData;

}

The above operation deconstructs the object passed to the function. Such operations can also be completed directly in the parameters:

const profileUpdate = ({ name, age, nationality, location }) => {

}

When the profileData is passed to the above function, the value is deconstructed from the function parameters for use within the function.

Simple fields write concise object literal declarations

ES6 adds some great features to make it easier to define objects.

See the following code:

const getMousePosition = (x, y) => ({
  x: x,
  y: y
});

getMousePosition is a simple function that returns an object with two properties. ES6 provides a syntax sugar that eliminates redundant writing like x: x. You can write x only once, and the interpreter will automatically convert it to x: x (or something with the same effect). Here is the same function rewritten with this syntax:

const getMousePosition = (x, y) => ({ x, y });

ES6 writes concise function declarations

In ES5, when we need to define a function in an object, we must use the function keyword like this:

const person = {
  name: "Taylor",
  sayHello: function() {
    return `Hello! My name is ${this.name}.`;
  }
};

When defining a function in an object with the syntax of ES6, you can delete the function keyword and colon. Take the following example:

const person = {
  name: "Taylor",
  sayHello() {
    return `Hello! My name is ${this.name}.`;
  }
};

Use class syntax to define constructors

ES6 provides a new syntax for creating objects, using the keyword class.

It is worth noting that class is just a syntax sugar. It does not strictly follow the object-oriented development specifications like languages such as Java, Python or Ruby.

In ES5, we usually define a constructor, and then use the new keyword to instantiate an object:

var SpaceShuttle = function(targetPlanet){
  this.targetPlanet = targetPlanet;
}
var zeus = new SpaceShuttle('Jupiter');

The class syntax simply replaces the constructor:

class SpaceShuttle {
  constructor(targetPlanet) {
    this.targetPlanet = targetPlanet;
  }
}
const zeus = new SpaceShuttle('Jupiter');

It should be noted that the class keyword declares a new function with a constructor added. When you create a new object with new, the constructor is called.

**Note: * * UpperCamelCase is the naming convention of ES6 class, just like SpaceShuttle above.

The constructor method is a special method used to create and initialize objects created by class.

Create a module script

At first, JavaScript played almost a small role in HTML web. Today, everything is different. Many websites are written almost entirely in JavaScript. In order to make JavaScript more modular, cleaner and easier to maintain, ES6 introduces a mechanism to share code among multiple JavaScript files. It can export part of the file for use by other files, and then import it as needed where it is needed. To use this function, you need to create a script with type module in the HTML document. Examples are as follows:

<script type="module" src="filename.js"></script>

Scripts that use the module type can use the import and export features

Create a default export with export default

In the export course, you learned the naming export syntax, which can reference some functions or variables in other files.

You also need to understand another syntax of export called default export. This syntax is usually used when there is only one value in the file to export. It is also often used to create return values for files or modules.

The following is an example of using export default:

export default function add(x, y) {
  return x + y;
}

export default function(x, y) {
  return x + y;
}

The first is a named function, and the second is an anonymous function.

Export default is used to declare a return value for a module or file. Only one value should be exported by default in each file or module. In addition, you cannot use export default with var, let, or const.

Promise

Create a JavaScript Promise

Promise is a solution for asynchronous programming - it will generate a value at some point in the future. Task completion can be divided into two cases: successful execution and failed execution. Promise is a constructor function, which needs to be created through the new keyword. The constructor parameter is a function that has two parameters - resolve and reject. They are used to judge the execution result of promise. The usage is as follows:

const myPromise = new Promise((resolve, reject) => {

});

Complete Promise through resolve and reject

Promise has three states: pending, fully, and rejected. The promise created in the previous challenge is always blocked in the pending state because the completion method of promise is not called. The resolve and reject parameters provided by promise are used to end promise. Resolve is called when promise succeeds, and reject is called when promise fails. As described below, these methods need to have a parameter.

const myPromise = new Promise((resolve, reject) => {
  if(condition here) {
    resolve("Promise was fulfilled");
  } else {
    reject("Promise was rejected");
  }
});

The above example uses strings as arguments to these functions, but the arguments can actually be in any format. Usually, it may be an object containing data that you can put on a website or elsewhere.

Deal with Promise completion with then

When a program takes an unknown time to complete (such as some asynchronous operations), it is generally a server request, and promise is very useful. The server request takes some time, and when it ends, it needs to perform some operations according to the server's response. This can be realized by the then method, and the then method will be triggered when promise completes the resolve. Examples are as follows:

myPromise.then(result => {

});

result is the parameter passed into the resolve method.

Use catch to handle Promise failure

The catch method is called when promise fails. When the reject method of promise is executed, it will be called directly. The usage is as follows:

myPromise.catch(error => {

});

error is the parameter passed into the reject method.

Topics: Javascript Front-end TypeScript