Let and const

In JavaScript, we used to use the key var to define variables. After ES6, we added two new keywords to define variables, namely let and const. For variables, in ES5 var variables are promoted before all functions and statements in scope, whereas in ES6 let variables are not. Let variables create a temporary dead zone in their corresponding code block until the variable is declared. Let and const can both declare block-level scope, similar to var, in that let does not promote variables and is locked in the current block.

A very simple example:

Function test() {if(true) {console.log(a) Test () // a is not defined function test() {if(true) {let a = 1} console.log(a)} test() // a is not definedCopy the code

The only correct way to use it: declare first, access later.

function test() {
    if(true) {
      let a = 1
      console.log(a)
    }
}
test() // 1
Copy the code

Const declares constants. Once declared, they cannot be changed, and constants must be initialized. Const is a constant and is not allowed to change the default assignment. However, if you define an Object, you can change the value of the property inside the Object.

Const type = {a: 1} type.a = 2 console.log(type) // {a: 2}Copy the code

** Both const and let are valid within the current block, are destroyed outside the block, and do not have variable promotion (TDZ). They cannot be declared twice. ** Differences: **const cannot be reassigned. Variables declared by lets can be repeatedly assigned. What const actually guarantees is not that the value of the variable cannot be changed, but that the data stored at the memory address to which the variable points cannot be changed. For data of simple types (values, strings, booleans), the value is stored at the memory address to which the variable points, and is therefore equivalent to a constant. But for complex type data (mainly objects and arrays), variable pointing to the memory address, save only a pointer to the actual data, const can guarantee the pointer is fixed (i.e., always points to the other a fixed address), as far as it is pointing to the data structure of variable, is completely unable to control. Therefore, declaring an object as a constant must be done with great care.

If a variable is declared in a for loop using var, it will jump out of the body of the loop and pollute the current function.

for(var i = 0; i < 5; i++) { setTimeout(() => { console.log(i) //5, 5, 5, 5, 5 }, 0)} console.log(I) {console.log(I); i < 5; I ++) {setTimeout(() => {console.log(I)// 0,1,2,3,4}, 0)} console.log(I)// I is not defined I cannot contaminate external functionsCopy the code

In real development, we choose to use var, let, or const depending on whether our variables need to be updated or not. Usually we want variables to be protected from malevolent modification and use lots of const. Use const declarations. When declaring an object, const is also recommended. When you need to change the value of a declared variable, use let instead.

The five basic data types are Undefined, Null, Boolean, Number, and String. The reference type Object is used to form all data types in JavaScript. A new data type named symbol has been added, which as its name implies means unique, meaning that each symbol type is unique and does not duplicate any other symbol. A new value of type Symbol can be created by calling the Symbol() method, which is unique and not equal to any value.

var mySymbol=Symbol();
console.log(typeof mySymbol) //"symbol"
Copy the code

2. String

ES6 string new method

**UTF-16 code points: **ES6 enforces utF-16 string encoding. Please find utF-16 on your own.

**codePointAt() : ** This method supports UTF-16, takes the position of the encoding unit instead of the string position as an argument, and returns a code point corresponding to a given position in the string, that is, an integer value.

String.fromcodepoiont () : The opposite of codePointAt, retrieves the code point of a character in a String, or generates a character from the specified code point.

** Normalize () : ** Provides a standard form of Unicode, taking an optional string parameter to indicate that a standard form of Unicode should be applied.

In ES6, three new methods have been added. Each method takes two parameters, a substring to detect, and the index position to start matching.

The template string is one of the basic types in JavaScript. It is probably the most frequently used type except for objects. Strings contain methods such as substr, replace, indexOf,slice, etc. ES6 introduced the template string feature, which is represented by backquotes. You can represent multi-line strings and do text interpolation (using template placeholders).

// Console. log("hello world 1\n\ hello cala"); // "hello world // hello cala" // Console. log(' Hello world string text line 2 '); // "hello world // hello cala"Copy the code

You can use ${} to represent template placeholders, and you can pass variables you have defined into brackets, for example:

var name="cala";
var age=22;
console.log(`hello,I'am ${name},my age is ${age}`)
//hello,I'am cala,my age is 22
Copy the code

**includes(STR, index) : ** Returns true if the specified text is detected in the string, false otherwise.

let t = 'abcdefg'
if(t.includes('cde')) {
  console.log(2)
}
//true
Copy the code

**startsWith(STR, index) : ** Returns true if the specified text is detected at the beginning of the string, false otherwise.

let t = 'abcdefg'
if(t.startsWith('ab')) {
  console.log(2)
}
//true
Copy the code

**endsWith(STR, index) : ** Returns true if the specified text is detected at the end of the string, false otherwise.

let t = 'abcdefg'
if(t.endsWith('fg')) {
  console.log(2)
}
//true
Copy the code

If you only need to match a string for a substring, the new method is recommended, and if you need to find the location of the matching string, use indexOf().

Three, functions,

The default argument to the function

In ES5, we pass parameters to a function and then set default values inside the function, as follows.

function a(num, callback) { num = num || 6 callback = callback || function (data) {console.log('ES5: ', data)} callback(num * num) } a() //ES5: Callback a(10, function(data) {console.log(data * 10) // 1000, callback a(10, function(data * 10) {console.Copy the code

In ES6, we use the new default writing

function a(num = 6, callback = function (data) {console.log('ES6: ', data)}) { callback(num * num) } a() //ES6: A (10, function(data) {console.log(data * 10) // 1000, console.log(data * 10) // 1000, console.log(data * 10) // 1000, console.log(data * 10)})Copy the code

Iv. Arrow function (=>)

(The arrow function is very important, so I will mention it briefly and write an article about it later.)

const arr = [5, 10]
const s = arr.reduce((sum, item) => sum + item)
console.log(s) // 15
Copy the code

Arrow functions use this differently from ordinary functions. Ordinary functions in JavaScript have their own this value, which can be divided into: ordinary functions: When the function is called as a global function, this refers to the global object. When the function is called as a method in the object, this refers to the new object. When the function is called as a constructor, this refers to the new object. Bind changes the pointer to the arrow function of this: 1. The arrow function does not have this; the this inside the function comes from the nearest non-arrow function of its parent, and it cannot change the pointer to this. Arrow functions don’t have super. Arrow functions don’t have arguments. Arrow functions don’t have new. No prototype. 7. No support for duplicate named parameters.

Simple understanding of arrow functions

1. The left side of the arrow function represents the input parameters and the right side represents the output results.

const s = a => a
console.log(s(2)) // 2
Copy the code

In arrow functions, this belongs to the lexical scope and is directly determined by the context. For ordinary functions that point to indefinite this, it is easier to process this as follows:

Function Man(){this.age=22; return function(){ this.age+1; } } var cala=new Man(); Console. log(cala())//undefined //ES6 arrow function Man(){this.age=22; return () => this.age+1; } var cala=new Man(); console.log(cala())//23Copy the code

Arrow functions have no arguments(we can use rest arguments instead), no archetypes, and no new keyword (e.g. :

// no arguments var foo=(a,b)=>{return arguments[0]*arguments[1]} console.log(foo(3,5)) // no arguments var Obj = () => {}; console.log(Obj.prototype); Var Obj = () => {"hello world"}; var o = new Obj(); // TypeError: Obj is not a constructorCopy the code

The arrow function sorts the array

Const arr = [10, 50, 30,40, 20] const s = arr.sort((a, b) => console.log(s) // [10,20,30,40,50]Copy the code

Tail-call optimization tail-call refers to calling a new function when the function returns. Since the implementation of the tail-call needs to be stored in memory, in a loop body, if there are any tail-calls to the function, your memory may be full or overflow.

In ES6, the engine optimizes tail-calls for you. You don’t need to optimize them yourself, but the following three requirements should be met: (1) a function is not a closure; (2) a tail-call is the last statement of a function; (3) the result of a tail-call is returned as a function

In the ES5 era, recursion was not recommended because recursion affected performance. But with tail-call optimization, the performance of recursive functions has improved.

// use strict; function a(n, p = 1) { if(n <= 1) { return 1 * p } let s = n * p return a(n - 1, Let sum = a(3) console.log(sum) // 6Copy the code

5. Add methods for ES6 objects

The object.assign () method is used to copy the values of all enumerable attributes from one or more source objects to the target Object. It will return the target object. The object. assign method copies only the enumerable properties of the source Object itself to the target Object. This method uses the source object’s [[Get]] and the target object’s [[Set]], so it calls the relevant getter and setter. Therefore, it assigns attributes, rather than just copying or defining new attributes. If the merge source contains getters, this may make it unsuitable to merge the new properties into the stereotype. To defined properties (including its enumerable) is copied to the prototype, the Object should be used. The getOwnPropertyDescriptor () and Object. The defineProperty (). Both String and Symbol attributes are copied. Merge objects

var o1 = { a: 1 }; var o2 = { b: 2 }; var o3 = { c: 3 }; var obj = Object.assign(o1, o2, o3); console.log(obj); // { a: 1, b: 2, c: 3 } console.log(o1); // {a: 1, b: 2, c: 3}, note that the target object itself also changes.Copy the code

Merge objects with the same properties

var o1 = { a: 1, b: 1, c: 1 };
var o2 = { b: 2, c: 2 };
var o3 = { c: 3 };
var obj = Object.assign({}, o1, o2, o3);
console.log(obj); // { a: 1, b: 2, c: 3 }
Copy the code

Map and Set

Both maps and sets are called sets, but they are also different. A Set is often used to check for the presence of a key name in an object, and a Map collection is often used to retrieve existing information. A Set is an ordered list of independent, non-repeating values. Compare Array with Set

Both are containers that store multiple values and can be converted to each other, but there are differences in usage scenarios. As follows:

The indexOf method is less efficient than the HAS method of a Set. A Set does not have duplicate values (this feature can be used to delete an Array). A Set deletes a value by delete, whereas an Array can only be deleted by splice. Many new Array methods map, filter, some, every, etc. are not Set (but through the two can be converted to each other to use) Object and map comparison

Object is string – value, Map is value – value

The Object key is of string type, and the Map key is of any type. You can calculate the size of the Object manually. Map.size can get the size of the Map. Map= object.create (null)

Set of operations

From (set) let arr = [...set] // Instance attributes (inherited from set) set.constructor === set Set.add (1) // Add a value set.delete(1) // Delete a value set.has(1) // Check whether there is a value (indexOf in Array) set.clear() // Clear all values // Set.keys () // traversal of key names set.values() // Traversal of key values set.entries() // Traversal of key value pairs set.foreach () // For (let key of set.keys()){} for (let val of set.values()){} for (let entry of set.entries()){} // Set = new set (arr) set = new set ([...set].map((x) => x = x * 2)) set = new set ([...set].filter((x) => x > 2))Copy the code

A collection of Map methods

Set (1,2) map.get(1) map.delete(1) map.constructor === map map.size Map.has (1) map.clear() // Traverse method map.keys() map.values() map.entries() map.foreach () // Convert map to array map = new Map ([[' key ', 'val'], [2, 1]]) / / request double let members array arr = Map [...] / / it is worth noting that the Map keys are bound to memory Map. The set ([1]. 's') map.get([1]) let arr = [1] let arr1 = [1] map.set(arr, 's') map.get(arr) map.set(arr1, 's') map.get(arr1)Copy the code

For an in-depth understanding of sets and maps, see “In Depth: Set and Map Data Structures in ES6, And Conversions between Maps and Other Data Structures.”

Iterators (iterators)

Entries () returns iterator: returns key-value pairs

// array const arr = ['a', 'b', 'c']; for(let v of arr.entries()) { console.log(v) } // [0, 'a'] [1, 'b'] [2, 'c'] //Set const arr = new Set(['a', 'b', 'c']); for(let v of arr.entries()) { console.log(v) } // ['a', 'a'] ['b', 'b'] ['c', 'c'] //Map const arr = new Map(); arr.set('a', 'a'); arr.set('b', 'b'); for(let v of arr.entries()) { console.log(v) } // ['a', 'a'] ['b', 'b']Copy the code

Values () returns iterator: returns the value of the key-value pair

// array const arr = ['a', 'b', 'c']; for(let v of arr.values()) { console.log(v) } //'a' 'b' 'c' //Set const arr = new Set(['a', 'b', 'c']); for(let v of arr.values()) { console.log(v) } // 'a' 'b' 'c' //Map const arr = new Map(); arr.set('a', 'a'); arr.set('b', 'b'); for(let v of arr.values()) { console.log(v) } // 'a' 'b'Copy the code

Keys () returns the iterator: returns the key of the key-value pair

// array const arr = ['a', 'b', 'c']; for(let v of arr.keys()) { console.log(v) } // 0 1 2 //Set const arr = new Set(['a', 'b', 'c']); for(let v of arr.keys()) { console.log(v) } // 'a' 'b' 'c' //Map const arr = new Map(); arr.set('a', 'a'); arr.set('b', 'b'); for(let v of arr.keys()) { console.log(v) } // 'a' 'b'Copy the code

Although the three built-in iterator methods are listed above, different collection types also have their own default iterators. In for of, the default iterator for arrays and sets is values(), and for Map is entries().

For the cycle

The object itself does not support iteration, but we can add a generator of our own that returns an iterator of key and value, and then use a for of loop to deconstruct the key and value.

const obj = {
  a: 1,
  b: 2,
  *[Symbol.iterator]() {
    for(let i in obj) {
      yield [i, obj[i]]
    }
  }
}
for(let [key, value] of obj) {
  console.log(key, value)
}
// 'a' 1, 'b' 2
Copy the code

String iterator

const str = 'abc';
for(let v of str) {
  console.log(v)
}
// 'a' 'b' 'c'
Copy the code

ES6 adds several new methods to arrays: find(), findIndex(), fill(), copyWithin()

1. Find () : Passes a callback function that finds the first element in the array that matches the current search rule, returns it, and terminates the search.

const arr = [1, "2", 3, 3, "2"]
console.log(arr.find(n => typeof n === "number")) // 1
Copy the code

FindIndex () : Passes a callback function that finds the first element in the array that matches the current search rule, returns its index, and terminates the search.

const arr = [1, "2", 3, 3, "2"]
console.log(arr.findIndex(n => typeof n === "number")) // 0
Copy the code

3. Fill () : replace the element in the array with a new element.

arr.fill(value, start, end)
Copy the code

4. CopyWithin () : Selects an index of the array and copies elements from there, starting from 0 by default. You can also specify a range of elements to copy.

Arr. CopyWithin (target, start, end) const arr = [1,2,3, 4, 5] console.log(arr.copywithin (3)) // [1,2,3,1,2] Const arr1 = [1,2,3, 4, 5] console.log(arr1.copywithin (3, 1)) // [1,2,3, 3] Copies the array from the element with subscript 3, Specifies that the first element to be copied has an index of 1, So 4, 5 is replaced with 2,3 const arr2 = [1,2,3, 4, 5] console.log(arr2.copywithin (3, 1,2)) // [1,2,3,2,5] copies the array from the element with subscript 3, specifying the first to copyCopy the code

ES6 classes class, Promise, and asynchronous programming, Proxy, and Reflection apis are more complex, but I’ll write more about them later.