Introduction to new features of ECMAScript 6

Introduction

ECMAScript 6.0 (hereinafter referred to as ES6) is the next-generation standard of the JavaScript language, officially released in June 2015. Its goal is to make JavaScript language can be used to write complex large-scale applications and become an enterprise-level development language.

Today we will explain the new syntax features introduced in ES6.

The relationship between ECMAScript and JavaScript

In November 1996, Netscape, the creator of JavaScript, decided to submit JavaScript to ECMA, the International Organization for Standardization.

In 1997, ECMA issued the 262 standard document ECMAScript 1.0.

The relationship between ECMAScript and JavaScript is that the former is the specification of the latter, and the latter is an implementation of the former.

Let's take a look at the release history of ECMAScript:

Since the release of ES2015, that is, ES6 in 2015, ECMAScript has been released to ES2020 at a release rate of one version per year.

Later articles we will explain the new features of these new versions of ECMAScript.

let and const

ES6 introduced let and const to solve the various problems of var variables before.

Before ES6, the scope of variables in JS had two types: global scope and function scope.

The global scope is well understood. When we start to write JavaScript in the browser console or Node.js interactive terminal, we enter the so-called global scope.

Variables in the global scope can be accessed in any other scope.

The function scope is the variable defined inside the function, which can be accessed inside the function.

There are some problems with these two scopes:

  1. Variable promotion

The var command will have "variable promotion" phenomenon, that is, the variable can be used before the declaration, and the value is undefined.

// var 的情况 
console.log(foo);  // 输出undefined 
var foo = 2; 
  1. Variable coverage

When we use global variables in the function scope, if a variable with the same name is defined in the function scope, no matter where it is defined, the global variable will be overwritten. As follows:

var tmp = new Date(); 
function f() {
    
     
console.log(tmp); 
if (false) {
    
     var tmp = "hello world"; 
} } 
f(); // undefined
  1. Variable disclosure

Variable disclosure means that we only wanted to use the variables in a small scope, but the result was leaked outside the scope, as shown below:

var s = 'hello'; 
for (var i = 0; i < s.length; i++) {
    
     
console.log(s[i]); 
} 
console.log(i); // 5
~~

为了解决上面两个问题,ES6引入了letconst。

这两个都是块级作用域。不同的是const定义的变量初始化之后就不能变化了。

什么是块级作用域呢?类似于 ifswitch 条件选择或者 forwhile 这样的循环体即是所谓的块级作用域,或者更简单一点使用大括号括起来的就叫做块级作用域。

块级作用域的最大好处就是不会产生作用域提升,如下所示:

~~~js
{
    
     
let a = 10; 
var b = 1; 
} 
a // ReferenceError: a is not defined. 
b // 1

Destructuring assignment

What is destructuring assignment?

ES6 allows you to extract values ​​from arrays and objects and assign values ​​to variables according to a certain pattern, which is called destructuring.

As follows:

let [a, b, c] = [1, 2, 3];
let [ , , third] = ["foo", "bar", "baz"];
let [x, , y] = [1, 2, 3];
let [head, ...tail] = [1, 2, 3, 4];

let [x, y] = [1, 2, 3];

Destructuring assignment can also set default values. Let’s look at the following examples:

let [foo = true] = []; 
foo // true

let [x, y = 'b'] = ['a']; 
// x='a', y='b' 

let [x, y = 'b'] = ['a', undefined]; 
// x='a', y='b’

let [x = 1] = [undefined]; 
x // 1
let [x = 1] = [null]; 
x // null

If the default value of destructuring is a function, then lazy assignment can be triggered:

function f() {
    
     
console.log('aaa'); 
} 

let [x = f()] = [1];

In the above example, the f function will not be executed.

In addition to structure variables, you can also structure objects:

let {
    
     bar, foo } = {
    
     foo: "aaa", bar: "bbb" }; 
foo // "aaa" 
bar // "bbb" 

let {
    
     baz } = {
    
     foo: "aaa", bar: "bbb" }; 
baz // undefined

var {
    
     foo: baz } = {
    
     foo: 'aaa', bar: 'bbb' }; 
baz // "aaa" 

let obj = {
    
     first: 'hello', last: 'world' }; 
let {
    
     first: f, last: l } = obj; 
f // 'hello' 
l // 'world'

Destructuring also supports nested structures:

let obj = {
    
     p: [ 'Hello', {
    
     y: 'World' } ] }; 

let {
    
     p: [x, {
    
     y }] } = obj; 

x // "Hello" 
y // "World"

Destructuring assignment has two very important functions.

The first is to exchange variables:

let x = 1; 
let y = 2; 
[x, y] = [y, x];

We can no longer use intermediate variables and directly interact with the values ​​of the two variables.

The second role is to return multiple values ​​from the function:

// 返回一个数组 
function example() {
    
     return [1, 2, 3]; } 
let [a, b, c] = example(); 

// 返回一个对象 
function example() {
    
     return {
    
     foo: 1, bar: 2 }; } 
let {
    
     foo, bar } = example();

//提取JSON数据
let jsonData = {
    
     id: 42, status: "OK", data: [867, 5309] }; 
let {
    
     id, status, data: number } = jsonData;

Array expansion

The Array.from method in ES6 is used to convert the following two types of objects into real arrays:

  • Array-like object
  • Iterable objects (including the new data structures Set and Map of ES6).

What is an array-like object?

The so-called array-like objects have only one essential feature, that is, they must have a length attribute. Therefore, any object with a length property can be converted to an array through the Array.from method.

The following variables are array-like variables:

let arrayLike = {
    
     '0': 'a', '1': 'b', '2': 'c', length: 3 }; 

How to convert this array-like object into an array?

// ES5的写法 
var arr1 = [].slice.call(arrayLike); 
// ['a', 'b', 'c']

// ES6的写法 let arr2 = Array.from(arrayLike); 
// ['a', 'b', 'c']

Let's look at the usual usage scenarios:

// NodeList对象 
let ps = document.querySelectorAll('p'); 
Array.from(ps).forEach(function (p) {
    
     console.log(p); }); 

// arguments对象 
function foo() {
    
     var args = Array.from(arguments); 
// ... 
}

What is a traversable object?

As long as it is a data structure deployed with the Iterator interface, it is called a traversable object.

Let's look at the following example:

Array.from('hello') // ['h', 'e', 'l', 'l', 'o'] 
let namesSet = new Set(['a', 'b']) 
Array.from(namesSet) // ['a', 'b']

At the same time, the spread operator (...) is also introduced. Through the spread operator, it can also be easily converted to an array object:

function foo() {
    
     var args = [...arguments]; } // arguments对象 
[...document.querySelectorAll('div')] // NodeList对象 

The Array.from method can also receive a second parameter to operate on the elements in the array:

Array.from(arrayLike, x => x * x); 
// 等同于 
Array.from(arrayLike).map(x => x * x); 

Array.from([1, 2, 3], (x) => x * x) 
// [1, 4, 9]

The Array.of method can easily create a new array:

Array.of(3, 11, 8) // [3,11,8] 
Array.of(3) // [3] 
Array.of(3).length // 1

Array() // [] 
Array(3) // [, , ,] 
Array(3, 11, 8) // [3, 11, 8]

Function extension

ES6, can support the default value of the function:

function log(x, y = 'World') {
    
     console.log(x, y); } 
function Point(x = 0, y = 0) {
    
     this.x = x; this.y = y; }

The default value of the function can be combined with the default value of destructuring assignment:

function foo({
    
    x, y = 5}) {
    
     console.log(x, y); } 
foo({
    
    }) // undefined, 5 
foo({
    
    x: 1}) // 1, 5 
foo({
    
    x: 1, y: 2}) // 1, 2 
foo() // TypeError: Cannot read property 'x' of undefined

Next, let's look at a complex example:

// 写法一 
function m1({
    
    x = 0, y = 0} = {
    
    }) 
{
    
     return [x, y]; } 

// 写法二 
function m2({
    
    x, y} = {
    
     x: 0, y: 0 }) 
{
    
     return [x, y]; }

Let's take a look, what is the difference between the above two writing methods?

When the function has no parameters:

m1() // [0, 0] 
m2() // [0, 0] 

When both x and y have values:

m1({
    
    x: 3, y: 8}) // [3, 8] 
m2({
    
    x: 3, y: 8}) // [3, 8] 

When x has a value, y has no value:

m1({
    
    x: 3}) // [3, 0] 
m2({
    
    x: 3}) // [3, undefined] 

When both x and y have no value:

m1({
    
    }) // [0, 0]; 
m2({
    
    }) // [undefined, undefined] 
m1({
    
    z: 3}) // [0, 0] 
m2({
    
    z: 3}) // [undefined, undefined]

Do you see the difference? The destructuring assignment of m1 has a default value of 0 for x and y. The destructuring assignment of m2 has no default value for x and y.

Author: flydean program those things

Link to this article: http://www.flydean.com/ecmascript-6-startup/

Source of this article: flydean's blog

Welcome to pay attention to my official account: the most popular interpretation of "programs", the most profound dry goods, the most concise tutorials, and many tips you don't know are waiting for you to discover!

Guess you like

Origin blog.csdn.net/superfjj/article/details/108724478