In the process of learning ES6, in order to facilitate their review, as well as view the API to do a minimalist use case introduction. Correct any mistakes you make.

A let and const

1.let

(1) A curly bracket is a block-level scope, and variables declared by let are only valid in their own scope; (2) ES6 forces the strict mode to be enabled, and the variable cannot be referenced if it is not declared, so Uncaught ReferenceError will be reported

function test() {
  for (let i = 1; i < 3; i++) {
    console.log(i)
  }
  console.log(i);  // Uncaught ReferenceError: i is not defined
}
test(a);Copy the code

(3) Let cannot be declared repeatedly

function test() {
  let a = 1; 
  let a = 2;
}
test(a);Copy the code

(4) There is no variable promotion in let (there is a problem here)

// var case console.log(a); Var a = 2; //letThe situation of the console. The log (b); / / error ReferenceErrorlet b = 2;
Copy the code

2.const

(1) Const must be assigned after the declaration or the compiler will fail; (2) Const cannot be modified;

Const PI = 3.14; // PI = 2; // const PI; console.log(PI);Copy the code

(3) Const if it is an object, add attributes to the object or modify the attributes of a; Json is a pointer to a memory address. The point of the pointer does not change, but the contents of the memory address that the JSON pointer points to can change.

const json = {
  a: 2
}
json.a = 3;
json.b = 3;
console.log(json.a)   //3
console.log(json.b)   //3
Copy the code

Two: Deconstructing assignment

1. Basic usage

Let’s start with two examples of what is deconstructed assignment

{
  let a, b, rest;
  [a, b, rest] = [1, 2];
  console.log(a, b, rest);   //1 2 undefined
}
Copy the code
{
  leta, b, rest; [a, b, ...rest] = [1, 2, 3, 4, 5, 6, 7]; console.log(a, b, rest); //1 2 [3, 4, 5, 6, 7]}Copy the code

2. Object deconstruction assignment

{
  leta, b; ({ a, b } = { a: 1, b: 2 }); // the order of a, b does not affect the structure result console.log(a, b); / / 1 2}Copy the code

3. The default value

{
  leta, b, rest; [a, b, rest = 3] = [1, 2]; console.log(a, b, rest); // 1 2 3}Copy the code

4. Practical application

Exchange of variables

{
  let a = 1;
  letb = 2; [a, b] = [b, a]; console.log(a, b); / / 2, 1}Copy the code

Receives the value returned by the function

{
  function f() {
    return [12, 13];
  }
  leta, b; [a, b] = f(); console.log(a, b); / / 12 13} {function f() {
    return[12, 13, 14, 15, 16] }leta, b; [a, , , b] = f(); Console. log(a, b); console.log(a, b); // 12 16} {function f() {
    return[12, 13, 14, 15, 16] }leta, b; [a, , ...b] = f(); Console. log(a, b); // 12 [14, 15, 16]}Copy the code

5. The application of object deconstruction assignment

{
  let o = { p: 42, q: true };
  let{ p, q } = o; console.log(p, q); / / 42true
}

{
  let{a = 10, b = 11} = {a: 3} // Change the default value of the object console.log(a,b); / / 3, 11}Copy the code

6. Simple application examples of deconstructing assignment

{
  let metaData = {
    title: 'abc'.test: [{
      title: 'gaojingbo',
      desc: 'description'}}]let { title: esTitle, test: [{ title: cnTitle }] } = metaData;
  console.log(esTitle, cnTitle);
}
Copy the code

Extension of three regulars

1. Constructor to create the re

{
  let regex1 = new RegExp('xyz'.'i');
  let regex2 = new RegExp(/xyz/i);
  console.log(regex1.test('xyz123'), regex2.test('xyz123')); // true true


  let regex3 = new RegExp(/xyz/ig, 'i'); Console. log(regex3.flags); // The following modifiers override the previous modifiers console.log(regex3.flags); // get regular expression modifier in es6Copy the code

2. G modifier and Y modifier

The y modifier is similar to the G modifier in that it is a global match, and each subsequent match starts at the position following the last successful match. The difference is that the G modifier works as long as there is a match in the remaining position, while the Y modifier ensures that the match must start at the first remaining position.

{
  let s = 'bbb_bb_b';
  leta1 = /b+/g; // count g as long as it matchesleta2 = /b+/y; // y must be the next starting letter start match console.log('one', a1.exec(s), a2.exec(s)); Y modifiers must be matched from the first, and null console.log() is printed if the first is not b.'two', a1.exec(s), a2.exec(s)); // For the second match, the g modifier will match as long as it matches, and the y modifier must match console.log(a1.sticky, a2.sticky) from the next character immediately adjacent to it; // Check whether the y modifier is turned onfalse true
}
Copy the code

Output of one and two

3. U modifier (Unicode)

ES6 adds the U modifier to regular expressions, which stands for “Unicode mode” to properly handle Unicode characters larger than \uFFFF.

{
  console.log('u-1', /^\uD83D/.test('\uD83D\uDC2A')); // Replace the last four bytes with two characters console.log('u-2', /^\uD83D/u.test('\uD83D\uDC2A')); Console. log(/\u{61}/.test('a'));  // falseBraces represent a Unicode character, so u must be added to recognize console.log(/\u{61}/u.test('a')); // true

  console.log(`\u{20BB7}`);
  let s = '𠮷';
  console.log('u-1', /^.$/.test(s));  //falseThe string is larger than two bytes and must be decorated with the U modifier to match console.log('u-2', /^.$/u.test(s)); //true

  console.log('test-1'The (/ 𠮷 {2} /'𠮷 𠮷')); // false
  console.log('test-2', / 𠮷 {2} / u.t est ('𠮷 𠮷')); // true
}
Copy the code

Quad string extension

1. Unicode representation

{
  console.log('a'.'\u0061'); // a a
  console.log('s'.'\u20BB7'); // s ₻7 Treat the first two bytes as a whole console.log('s'.'\u{20BB7}'); // s 𠮷 unicode {}Copy the code

2. Comparison between codePointAt and charCodeAt

JavaScript does not handle 4-byte characters correctly, misreading the string length as 2, and the charAt method cannot read the entire character. The charCodeAt method only returns the values of the first and last two bytes, respectively. ES6 provides a codePointAt method that correctly handles 4-byte stored characters and returns a character code point.

{
   let s = '𠮷';
   console.log(s.length);  // 2
   console.log('0', s.charAt(0)); // 0 � //es5 does not handle multi-byte characters console.log('1', s.charAt(1)); / / 1 � the console. The log ('at0', s.charCodeAt(0));  //at0 55362
   console.log('at1', s.charCodeAt(1));  //at1 57271
   
   let s1 = '𠮷 a';
   console.log('length', s1.length); // 3
   console.log('code0', s1.codePointAt(0)); // code0 134071
   console.log('code0', s1.codePointAt(0).toString(16)); // Code0 es6 automatically treats multiple byte characters as a whole to console.log('code1', s1.codePointAt(1)); // code1 57271
   console.log('code2', s1.codePointAt(2)); // code2 97
}
Copy the code

3. FromCharCode and fromCodePoint

ES5 provides a string.fromCharcode method for returning corresponding characters from code points, but this method does not recognize a Unicode number greater than 0xFFFF. ES6 provides the String.fromCodePoint method, which can recognize characters larger than 0xFFFF, to compensate for the string. fromCharCode method. In effect, it is opposite to codePointAt method. Note that the fromCodePoint method is defined on a String, while the codePointAt method is defined on an instance of a String.

{
  console.log(String.fromCharCode('0x20bb7')); / / ஷ console. The log (String. FromCodePoint ('0x20bb7')) / / 𠮷}Copy the code

4. String traverser

{
  // es5
  let str = '\u{20bb7}abc';
  for (let i = 0; i < str.length; i++) {
    console.log('es5', str[i]); //� � a b c} //es6for (let code of str) {
    console.log('es6', code); // 𠮷 a b c}}Copy the code

5. Some common string apis

{
  let str = 'string';
  console.log('includes', str.includes('c')); // Check whether it is includedfalse
  console.log('start', str.startsWith('s')); // What does it start withtrue
  console.log('end', str.endsWith('ng')); // What does it end withtrue
  console.log('repeat', str.repeat(2)); // String repeated twice stringString}Copy the code

ES6 introduces the string completion length function. If a string is not of a specified length, the header or tail is completed. PadStart () is used for head completion and padEnd() for tail completion. Returns the original string if the length of the original string is equal to or greater than the specified minimum length. If the sum of the length of the completion string and the original string exceeds the specified minimum length, the completion string exceeding the number of bits is truncated.

{
    console.log('1'.padStart(2,'0')); // 01
    console.log('1'.padEnd(2,'0')); // 10
}
Copy the code

6. Template string

{
  let name = "List";
  let info = "hello world";
  let m = `i am ${name} ${info}`;
  console.log(m);  //i am List hello world
}
Copy the code

7. Label template

{
  let user = {
    name:'list',
    info:'hello world'
  }

  function fn(s,v1,v2){
    console.log(s,v1,v2);
    return s+v1+v2;
  }

  console.log(fn`i am ${user.name} ${user.info}The symbol is equivalent to a function parameter fn(I am)${user.name} ${user.info});
}
Copy the code

The output

8.String.row API

ES6 also provides a raw method for native String objects. The string. raw method, often used as a template String handler, returns a String with escaped slashes (that is, one more slash before the slash) corresponding to the template String after the substitution.

{
  console.log('raw '+String.raw`hi\nThe ${1 + 2}`)
  console.log('noRaw '+`hi\nThe ${1 + 2}`)}Copy the code

The output

V. Numerical expansion

Binary octal representation

Starting with ES5, octal is no longer allowed to be represented with the prefix 0 in strict mode, and ES6 further specifies that the prefix 0O is used. If you want to decimal string values prefixed with 0b and 0o, use the Number method.

{
  console.log('B',0b11010101010); // Binary representation, b case can be console.log('O',0O1237637236); // octal representation}Copy the code

2. Number. IsFinite () and Number. The isNaN ()

Number.isfinite () is used to determine whether a Number isFinite(infinite decimal), and number.isnan () is used to determine whether a Number is a decimal

{
  console.log('15',isFinite(15));    //true
  console.log('NaN',isFinite(NaN));  //false
  console.log('1/0',isFinite(1/0));  //false
  console.log('isNaN',Number.isNaN(15)); // false
  console.log('isNaN',Number.isNaN(NaN));  // true
}
Copy the code

3.Number.isInteger

Number.isInteger Is used to determine whether a Number is an integer

{
  console.log('13',Number.isInteger(13));      // true
  console.log('13.0'That Number. IsInteger (13.0)); //true 
  console.log('13.1'That Number. IsInteger (13.1)); //false
  console.log('13',Number.isInteger('13'));    // false
}
Copy the code

4. Number. MAX_SAFE_INTEGER, Number MIN_SFAE_INTEGER and isSafeInterger

MAX_SAFE_INTEGER,Number.MIN_SFAE_INTEGER indicates the range of values that JS can accurately represent. IsSafeInterger is used to determine whether this value is within the safe range.

{
  console.log(Number.MAX_SAFE_INTEGER,Number.MIN_SFAE_INTEGER);
  console.log('15',Number.isSafeInteger(15));
  console.log('9999999999999999999999',Number.isSafeInteger(9999999999999999999999));
}
Copy the code

5. Math. Trunc and Math. Sign

The math. trunc method is used to remove the fractional part of a number and return the integer part. The math. sign method is used to determine whether a number is positive, negative, or zero. For non-numeric values, they are converted to numeric values first.

{
  console.log('4.1', Math. Trunc (4.1)); //4 console.log('4.9', Math. Trunc (4.9)); //4 } { console.log('- 5',Math.sign(-5))    //-1
  console.log('5',Math.sign(5))      //+1
  console.log('0',Math.sign(0))      //0
  console.log('50',Math.sign(50))    //+1
  console.log('NaN',Math.sign(NaN))  //NaN
} 
Copy the code

6.cbrt

CBRT is used to compute the square root of a number

{
  console.log('1',cbrt(-1));   //-1
  console.log('8',cbrt(8)); / / 2}Copy the code

Sextuple extension

1. Array.of

The array. of method is used to convert a set of values to an Array. The main purpose of this method is to complement the Array constructor Array(). Array() behaves differently because of the number of arguments.

{
  letArr = Array. Of (1, 2, 3, 4); console.log('arr=',arr);  // arr= [1, 2, 3, 4]

  letemptyArr = Array.of(); console.log(emptyArr); / / / / compared with method of Array [] Array () / / [] to Array (3) / / /,,, Array (3, 11, 8) / /} [3, 11, 8]Copy the code

2.Array.from

The array. from method is used to turn two types of objects into true arrays: array-like objects and traversable objects (including the new data structures Set and Map in ES6).

<p> Hello </p> <p> HELLO </p> <p> hello </p> {let p = document.querySelectorAll('p');
  let pArr = Array.from(p);
  pArr.forEach(function(item){ console.log(item.textContent); }) console.log(array. from([1,3,5],function(item){returnItem * 2 / /,6,10 [2]}}))Copy the code

3.Array.fill

The fill method fills an array with the given value.

{
  console.log('fill-7'And [1, 3,'undefined'].fill(7)); / /,7,7 [7] the console. The log ('fill,pos',2,3,4,5,7,8, [1]. The fill,1,4 (7)); //[1, 7, 7, 7, 5, 7, 8]Copy the code

4. Entries (), keys() and values()

ES6 provides three new methods — entries(), keys() and values() — for traversing groups of numbers.

{
  for(letThe index of [1, 2, 3, 4] keys ()) {the console. The log ('index',index);
   // index 0
   // index 1
   // index 2
   // index 3
  }
  for(letThe value of [1, 2, 3, 4] values ()) {the console. The log ('value',value);
   // value 1
   // value 2
   // value 3
   // value 4
  }
  for(let,2,4,5,6 [index, value] of [1]. The entries ()) {the console. The log (index, value); // 0 1/1 2 // 2 4 // 3 5 // 4}}Copy the code

5.Array.copyWithin

Intercepts a number of a certain length and replaces it with the corresponding index

{the console. The log (,4,9,6,7,2,3 [1]. CopyWithin,3,5 (1)); / / [1, 6, 7, 6, 7, 2, 3] / / the location of the intercept 3-5 Numbers, from the position of index 1 began to replace the console. The log (,4,9,6,7,2,3 [1]. CopyWithin,3,6 (1)); // [1, 6, 7, 2, 7, 2, 3]}Copy the code

6. FindIndex and find

The find method of an array instance, used to find the first array member that matches the criteria. Its argument is a callback function that is executed by all array members until the first member that returns true is found, and then returned. If there is no qualified member, undefined is returned. The findIndex method on an array instance is used much like the find method, returning the location of the first qualified array member, or -1 if all members fail.

{the console. The log ([6]. Find (function(item){return item > 3}));   //4
  console.log([1,2,3,4,5,6].findIndex(function(item){return item > 3}));   // 3
}
Copy the code

7.includes

The array.prototype. includes method returns a Boolean value indicating whether an Array contains a given value, similar to the includes method of strings. ES2016 introduced this approach.

{the console. The log ([1, 2, NaN]. Includes (1)); //trueThe console. The log ([1, 2, NaN]. Includes (NaN)); //true
}
Copy the code

8. Extend operators

The spread operator (spread) is three points (…) . Converts an array to a comma-separated sequence of arguments.

console.log(... [1, 2, 3]) // 1 2 3 console.log(1, ... [2, 3, 4], 5) // 1 2 3 4 5 [...document.querySelectorAll('div')]
// [<div>, <div>, <div>]
Copy the code

Seven function extension

1. The default value

Before ES6, you could not specify default values for function arguments directly; ES6 allows you to set default values for function arguments, which are written directly after the parameter definition.

{
	function fn(x,y='hello'){// Console. log(x,y) can no longer appear after the default value; } fn('word');  // word hello
	fn('word'.'nihao')  // word nihao
}

{
	let a = 'nihao';
	function test(a,b=a){  //1.
		//leta = 1; Parameter variables are declared by default, so they cannot be usedletOr const console.log(a,b); }test('word'); // word word  
	test(a); //undefined undefined } {let a = 'nihao';
	function test(x,b=a){  //2.
		console.log(x,b)
	}
	test('hello'); // hello nihao }Copy the code

3. The rest parameters

ES6 introduces the REST parameter (of the form… Variable name), used to get extra arguments to a function so you don’t need to use the arguments object. The rest argument goes with a variable that puts the extra arguments into an array.

{
	functionfn(... arg){for(letv of arg){ console.log(v); }} fn (1, 2, 3, 4); //1 //2 //3 //4 } { console.log(... [1, 2, 3, 4]); // 1,2,3,4 console.log('a'. [1, 2, 3, 4]); / / a, 1, 2, 3, 4}Copy the code

Arrow function

ES6 allows functions to be defined using arrows (=>).

{
	let arr = v => v*2;
	console.log(arr(2));

	var sum = (num1, num2) => { returnnum1 + num2; } // If the arrow function has more than one statement in the code block, enclose them in braces, and usereturnStatement return. }Copy the code

The use note arrow function has several use note points.

(1) The this object inside the function is the object at which it is defined, not the object at which it is used.

(2) Cannot be used as a constructor, that is, cannot use the new command, otherwise an error will be thrown.

(3) You can’t use arguments. This object does not exist in the function body. If you do, use the REST argument instead.

(4) Yield cannot be used, so arrow functions cannot be used as Generator functions.

5. Binding this

The function-binding operators are two colons (::) side by side, with an object on the left and a function on the right. The operator automatically binds the object on the left as the context (this object) to the function on the right.

foo::bar; // Equivalent to bar.bind(foo); foo::bar(... arguments); // equivalent to bar.apply(foo, arguments); const hasOwnProperty = Object.prototype.hasOwnProperty;function hasOwn(obj, key) {
  return obj::hasOwnProperty(key);
}
Copy the code

The Tail Call refers to the last step of a function that is to Call another function.

{
	function fn1(x){
		console.log('fn1',x);
	}
	function fn2(x){
		returnfn1(x); // The call to fn1 must be done in the last step} fn2(2); }Copy the code

Eight Object Extension

1. Brief representation of properties

ES6 allows variables and functions to be written directly as properties and methods of objects. It’s much more concise.

{
	let a = 5,b=6;
	let es5 = {
		a:a,
		b:b
	}
	let es6 = {
		a,
		b
	}
	console.log(es5,es6)  // {a: 5, b: 6}  {a: 5, b: 6}


	let es5_fn = {   // 
		fn:function(){
			console.log('hello')}}let es6_fn = {
		fn(){
			console.log('hello')
		}
	}
	console.log(es5_fn.fn,es6_fn.fn);
}
Copy the code

2. Dynamic key values

Es6 allows the key of an attribute to be a dynamic variable

{
	let a = 'b';
	let es5_obj = {
		a:'c',
		b:'c'
	}
	let es6_obj = {
		[a]:'c'} console.log(es5_obj, es6_obj);} console.log(es5_obj, es6_obj); }Copy the code

3.Object.is

This method is equivalent to === in ES5 to determine whether attributes are equal

{
	console.log('is',Object.is('a'.'a'));  // true
	console.log('is',Object.is([],[]));    // falseArray objects have different addresses,}Copy the code

4.Object.assign

The object. assign method is used to merge objects. It copies all the enumerable attributes of the source Object to the target Object.

{
	console.log('copy',Object.assign({a:1},{b:2})); / / shallow copylet test = {a:2,b:3}
	for(let [key,value] of Object.entries(test){// iterate over console.log([key,value]); //[a:2] //[b:3] } }Copy the code

Nine Symbol

1

ES6 introduces a new primitive data type, Symbol, that represents unique values.

{
	let a1 = Symbol();
	let a2 = Symbol();
	console.log(a1===a2)   // false

	let a3 = Symbol.for('a3');
	let a4 = Symbol.for('a3');

	console.log(a3===a4);  //true
}
Copy the code

2. Some API of Symbol

Symbol.for can be used to name objects that have the same key value. Object. GetOwnPropertySymbols method returns an array, the member is the all of the current Object is used as the Symbol value of the property name. The reflect.ownkeys method can return all types of key names, including regular and Symbol key names.

{
	let a1 = Symbol.for('abc');
	let obj = {
		[a1]:123,
		abc:234,
		c:345
	}
	console.log(obj); 
	// abc:234
	// c:345
	// Symbol(abc):123

	Object.getOwnPropertySymbols(obj).forEach(function(item){
		console.log('symbol',item,obj[item]); //symbol Symbol(abc) 123
	})
	Reflect.ownKeys(obj).forEach(function(item){
		console.log(item,obj[item]); 
		//abc 234
		//c 345
		//Symbol(abc) 123
	})

}
Copy the code

Map and Set data structures

1. The basic usage of set

ES6 provides a new data structure, Set. It is similar to an array, but the values of the members are unique and there are no duplicate values. The Set itself is a constructor used to generate the Set data structure. The Set structure does not add duplicate values

{
	letlist = new Set(); list.add(2); list.add(3); console.log(list.size); / / 2letArr = [1, 2, 3, 4, 5];let list2 = new Set(arr);
	console.log(list2.size); //5

	console.log(list2) //{1, 2, 3, 4, 5}

	let,2,3,4,2,1 arr2 = [1]; // This can be treated as an arraylet list3 = new Set(arr2);
	console.log(list3) //{1, 2, 3, 4}

}
Copy the code

Add (value) : Adds a value and returns the Set structure itself. Delete (value) : deletes a value and returns a Boolean value indicating whether the deletion is successful. Has (value) : Returns a Boolean value indicating whether the value is a member of Set. Clear () : Clears all members with no return value.

{
	let arr = ['add'.'delete'.'clear'.'has'];
	letlist = new Set(arr); console.log(list); / / {"add"."delete"."clear"."has"}

	list.delete('add'); console.log(list); / / {"delete"."clear"."has"}

	console.log(list.has('clear')); // truelist.clear(); console.log(list); / / / / {}setTraversal method {let arr = ['add'.'delete'.'clear'.'has'];
		let list = new Set(arr);

		for(let key of list.keys()){
			console.log('keys',key)
			//keys add
			//keys delete
			//keys clear
			//keys has
		}
		for(let value of list.values()){
			console.log('values',value)
			//values add
			//values delete
			//values clear
			//values has
		}
		for(let [key,value] of list.entries()){
			console.log(key,value);
			//add add
			//delete delete
			//clear clear
			//has has
		}
		list.forEach(function(item){console.log(item)})
		   // add
		   // delete
		   // clear
		   // has
	}
}

Copy the code

2. Basic usage of WeakSet

WeakSet structure is similar to Set, which is also a collection of non-repeating values. However, it differs from Set in two ways. First, WeakSet members can only be objects, not other types of values. WeakSet objects are weak references, that is, garbage collection mechanism does not consider WeakSet’s reference to the object, that is, if other objects no longer reference the object, then garbage collection mechanism will automatically recover the memory occupied by the object, not considering the object still exists in WeakSet. Weakset.prototype. add(value) : Adds a new member to the WeakSet instance. Weakset.prototype. delete(value) : Clears the specified member of a WeakSet instance. Weakset.prototype. has(value) : Returns a Boolean value indicating whether a value is in

{
	const ws = new WeakSet();
	ws.add(1)
	// TypeError: Invalid value used in weak set
	ws.add(Symbol())
	// TypeError: invalid value used in weak set

	letWeakset = new weakset () // No clear,setMethod, cannot be traversedletObj = {} weakset.add(obj) // weekset.add(2) WeakSet must add object, weak reference console.log(weakset); }Copy the code

3. Basic usage of Map

ES6 provides Map data structures. It is a collection of key-value pairs similar to objects, but the range of “keys” is not limited to strings. Values of all types (including objects) can be used as keys. That is, the Object structure provides string-value correspondence, and the Map structure provides value-value correspondence

{
	const map = new Map([
	  ['name'.'Joe'],
	  ['title'.'Author']]); map.size // 2 map.has('name') / /true
	map.get('name') / /"Zhang"
	map.has('title') / /true
	map.get('title') / /"Author"
}
{
	let map = new Map();
	let arr = ['123'];
	map.set(arr,'456');
	console.log(map,map.get(arr)) // {["123"] = >"456"} "456"
}

{
	let map = new Map([['a', 123], ['b',456]]) console.log(map); / / {"a"= > 123,"b" => 456}
	console.log(map.size);  			//2
	console.log('123'+map.delete('a')); //true
	console.log(map)  					// {"b"=> 456} map.clear() console.log(map); / / {}}Copy the code

4. Some API of WeakMap

WeakMap only accepts objects as key names (except null) and does not accept values of other types as key names. Objects referenced by the key name of WeakMap are weak references, that is, the garbage collection mechanism does not take this reference into account. Therefore, as long as all other references to the referenced object are cleared, the garbage collection mechanism frees the memory occupied by the object. In other words, once it is no longer needed, the key name object and the corresponding key value pair in WeakMap will disappear automatically, without manually deleting the reference. WeakMap differs from Map in API mainly in two aspects. First, there is no traversal operation (that is, no key(), values() and entries() methods) and no size attribute. Because there is no way to list all the key names, the existence of a particular key name is completely unpredictable and depends on whether the garbage collection mechanism is running. One moment the key name is available, the next moment the garbage collection mechanism is suddenly running, and the key name is gone, so in case of uncertainty, there is a general rule that the key name is not available. Second, it cannot be cleared, that is, the clear method is not supported. Therefore, WeakMap has only four methods available: get(), set(), has(), delete().

{
	letWeakmap = new weakMap () // No clear,setMethod, cannot be traversedlet o = {}
	weakmap.set(o,123);
	console.log(weakmap.get(o));
}
Copy the code

11 Proxy and Reflect

1.Proxy

Proxy is used to modify the default behavior of certain operations, which is equivalent to making changes at the language level. Therefore, it is a kind of “meta programming”, that is, programming a programming language. Proxy can be understood as a layer of “interception” before the target object. All external access to the object must pass this layer of interception. Therefore, Proxy provides a mechanism for filtering and rewriting external access. The word Proxy is used to mean that it acts as a Proxy for certain operations.

{
  let obj = {
    name:'gaojingbo',
    time:'2017-08-13',
    emp:'123',}let temp = new Proxy(obj,{
    get(target,key){
          return target[key].replace('2017'.'2018');
    },
    set(target,key,value){
      if(key === 'name') {return target[key] = value;
      }else{
        return target[key];
      }
    },
    has(target,key){
      if(key === 'name') {return target[key];
      }else{
        return false;
      }
    },
    deleteProperty(target,key){
      if(key.indexOf('i') > -1){
        delete target[key];
        return true;
      }else{
        return target[key];
      }
    },
    ownKeys(target){
      returnObject.keys(target).filter(item=>item! ='name');
    }
  })

  console.log('get',temp.time);  //get 2018-08-13

  temp.time = '2018';
  console.log('set',temp.name,temp); //set gaojingbo   {name: "gaojingbo", time: "2017-08-13", temp: "123"}

  temp.name = 'hexiaofei';
  console.log('set',temp.name,temp); // set hexiaofei  {name: "hexiaofei", time: "2017-08-13", temp: "123"}

  console.log('has'.'name' in temp,'time' in temp);  //has true false

  delete temp.time;
  console.log('delete',temp);   //delete  {name: "hexiaofei", temp: "123"}

  console.log('ownkeys',Object.keys(temp)); / / /"emp"]}Copy the code

2.Reflect

Reflect objects, like Proxy objects, are a new API provided by ES6 for manipulating objects. The Reflect object is designed for several purposes. (1) Put some methods of Object that are clearly internal to the language (such as Object.defineProperty) on Reflect. At this stage, some methods are deployed on both Object and Reflect objects, and future new methods will only be deployed on Reflect objects. That is, from the Reflect object you can get the methods inside the language. (2) Modify the return result of some Object methods to make them more reasonable. For example, Object.defineProperty(obj, name, desc) throws an error if the attribute cannot be defined, while Reflect.defineProperty(obj, name, desc) returns false. (3) Make all Object operations functions. Some Object operations are imperative, such as name in obj and delete obj[name], while reflect.has (obj, name) and reflect.deleteProperty (obj, name) make them functional behavior. (4) Reflect object method and Proxy object method one by one, as long as the Proxy object method, you can find the corresponding method on Reflect object. This allows the Proxy object to easily call the corresponding Reflect method, completing the default behavior as a basis for modifying the behavior. That is, no matter how the Proxy changes the default behavior, you can always get the default behavior in Reflect.

{
  let obj = {
    name:'gaojingbo',
    time:'2017-08-13',
    emp:'123',
  }
  console.log('reflect get',Reflect.get(obj, 'name'));  // reflect get gaojingbo
  Reflect.set(obj,'name'.'hexaiofei');
  console.log(obj);  // {name: "hexaiofei", time: "2017-08-13", emp: "123"}
  console.log('reflect has', Reflect.has(obj,'name'));  //reflect has true
}
Copy the code

3. Simple applications

{
  function validator(target,validator) {
    return new Proxy(target,{
      _validator:validator,
      set(target,key,value,proxy){
        if(target.hasOwnProperty(key)){
          let va = this._validator[key];
          if(!!!!! va(value)){return Reflect.set(target,key,value,proxy);
          }else{throw Error(' cannot be set${key}to${value}`); }}else{
          throw Error(`${key}There is no `); } } }) } const personValidators={ name(value){return typeof value === 'string'
    },
    age(value){
      return typeof value === 'number' && value > 18;
    }
  }

  class Person{
    constructor(name,age) {
      this.name = name;
      this.age = age;
      return validator(this,personValidators)
    }
  }

  const person = new Person('lilei', 30); console.log(person); person.name = 48; }Copy the code

The basic syntax of the twelve classes

1. Introduction

ES6 provides a more traditional language approach, introducing the concept of classes as templates for objects. With the class keyword, you can define a class. Basically, ES6 classes can be seen as a syntactic candy that does most of what ES5 does. The new class writing method simply makes object prototype writing clearer and more like object-oriented programming syntax.

{
  class Parent {
    constructor(name='gaojingbo') { this.name = name; }}let v_parent = new Parent();
  console.log(v_parent);  //{name: "gaojingbo"}}Copy the code

2. The inheritance

Classes can be inherited through the extends keyword, which is much cleaner and more convenient than ES5’s inheritance through modified prototype chains.

{
  class Parent {
    constructor(name='gaojingbo') {
      this.name = name;
    } 
  }

  class child extends Parent {

  }
  let v_child = new child();
  console.log(v_child);  //{name: "gaojingbo"}}Copy the code

3.constructor

The constructor method is the default method of the class and is automatically called when an object instance is generated using the new command. A class must have a constructor method; if it is not explicitly defined, an empty constructor method is added by default.

4. The super keyword

The super keyword can be used as either a function or an object. In both cases, it’s used quite differently. In the first case, super, when called as a function, represents the constructor of the parent class. ES6 requires that the constructor of a subclass must execute the super function once. In the second case, super as an object, in a normal method, points to a prototype object of the parent class; In static methods, point to the parent class. Super () is used in the subclass constructor to get this context, so if this is used in constructor, you must call super() before using this, and if this is not used in constructor, you do not need to call super( )

{
  class Parent {
    constructor(name='gaojingbo') {
      this.name = name;
    } 
  }
  class child extends Parent {
    constructor(name='child'){
      super(name);
      this.type = 'child'}}let v_child = new child();
  console.log(v_child);  //{name: "child".type: "child"}}Copy the code

5. Getter and setter

As in ES5, you can use the get and set keywords inside a “class” to set the store and value functions for an attribute and intercept the access behavior of that attribute.

{
  class Parent {
    constructor(name='gaojingbo') {
      this.name = name;
    } 
    get longName() {return 'mk' + this.name;
    }
    setlongName(value){ // console.log(value); this.name = value; }}let v_parent = new Parent();
  console.log('get',v_parent.longName);  //get mkgaojingbo

  v_parent.longName = 'hello';
  console.log('get',v_parent.longName);  //get mkhello
}
Copy the code

6. Static methods

A class is the prototype of an instance, and all methods defined in a class are inherited by the instance. If you prefix a method with the static keyword, it means that the method is not inherited by the instance, but is called directly from the class. This is called a “static method”.

{
  class Parent {
    constructor(name='gaojingbo') {
      this.name = name;
    } 
    static tell(){
      console.log('tell'); }}let v_parent = new Parent();
  console.log(v_parent);  //{name: "gaojingbo"}
  Parent.tell(); // tell
}
Copy the code

7. Static properties

Static properties refer to properties of the Class itself, class.propName, not properties defined on the instance object (this).

{
  class Parent {
    constructor(name='gaojingbo') {
      this.name = name;
    } 
    
  }
  Parent.tell = 'nihao';

  let v_parent = new Parent();
  console.log(v_parent);  //{name: "gaojingbo"}
  console.log(Parent.tell);   // nihao
}
Copy the code

Thirteen Promise

Promise is a solution to asynchronous programming that makes more sense and is more powerful than traditional solutions — callback functions and events. It was first proposed and implemented by the community, and ES6 has written it into the language standard, unifying usage, and providing Promise objects natively. A Promise is simply a container that holds the result of an event (usually an asynchronous operation) that will end in the future. Syntactically, a Promise is an object from which to get messages for asynchronous operations. Promise provides a uniform API, and all kinds of asynchronous operations can be handled in the same way. Promise objects have two characteristics. (1) The state of the object is not affected by the outside world. The Promise object represents an asynchronous operation with three states: Pending, Fulfilled and Rejected. Only the result of an asynchronous operation can determine the current state, and no other operation can change the state. That’s where the name “Promise” comes from. Its English name means “Promise,” indicating that nothing else can change it. (2) Once the state changes, it will never change again, and this result can be obtained at any time. There are only two possibilities for a Promise object to change its state: from Pending to Fulfiled and from Pending to Rejected. As long as these two things are happening the state is fixed, it’s not going to change, it’s going to stay the same and that’s called Resolved. If the change has already occurred, you can add a callback to the Promise object and get the same result immediately. This is quite different from an Event, which has the characteristic that if you miss it and listen again, you will not get the result.

Note that in order to facilitate the writing, the “Resolved” in this chapter only refers to the regrettable state, excluding the Rejected state.

With the Promise object, asynchronous operations can be expressed as a flow of synchronous operations, avoiding layers of nested callback functions. In addition, Promise objects provide a unified interface that makes it easier to control asynchronous operations.

Promise also has some downsides. First, there is no way to cancel a Promise; once it is created, it is executed immediately and cannot be cancelled halfway through. Second, if you don’t set a callback function, errors thrown inside a Promise won’t be reflected externally. Third, when you are in a Pending state, you have no way of knowing what stage of progress you are currently in (just beginning or just finishing).

If certain events are repeated over and over again, using the Stream pattern is generally a better choice than deploying promises.

1. Basic usage

The Promise constructor takes a function as an argument, resolve and reject. They are two functions that are provided by the JavaScript engine and do not need to be deployed themselves.

The resolve function changes the state of the Promise object from “unfinished” to “successful.” It will be called when the asynchronous operation succeeds and will pass the result of the asynchronous operation as an argument. The Reject function changes the state of the Promise object from “unfinished” to “failed” (i.e., from Pending to Rejected). It is called when the asynchronous operation fails and passes the error reported by the asynchronous operation as a parameter.

After the Promise instance is generated, you can use the THEN method to specify the Resolved and Rejected state callback functions, respectively.

// ES5 callback {let ajax = function(callback){
    console.log('nihao');
    setTimeout(function(){
      callback && callback.call()
    },1000)
  }
  ajax(function(){
    console.log('timeout1'); })} // es6 Promiselet ajax = function(){
    console.log('wohao');
    return new Promise((resolve, reject) => {
      setTimeout(function(){ resolve(); }, 1000); }); } ajax().then(function(){
    console.log('promise'.'timeout1');
  })
}

promise.then(function(value) {// promise:function(error) {
  // failure
});
Copy the code

2.Promise.prototype.then()

Promise instances have THEN methods, that is, then methods defined on the prototype object Promise.Prototype. It adds a callback function to the Promise instance when the state changes. As mentioned earlier, the first argument to the THEN method is the callback in the Resolved state and the second argument (optional) is the callback in the Rejected state. The then method returns a new Promise instance (note, not the original Promise instance). So you can write it chained, where a then method is followed by another THEN method.

{
  let ajax = function(){
    console.log('dajiahao');
    return new Promise((resolve, reject) => {
      setTimeout(function(){ resolve(); }, 1000); }); }; ajax().then(function() {return new Promise((resolve, reject) => {
      setTimeout(function(){
        resolve();
      },2000)
    });
  })
  .then(function(){
    console.log('timeout3'); })}Copy the code

3.Promise.prototype.catch()

The promise.prototype. catch method is an alias for. Then (null, Rejection) that specifies the callback when an error occurs.

{
  let ajax = function(num){
    console.log('dajiahao');
    return new Promise((resolve, reject) => {
      if(num>6){
        console.log('6');
      }else{
        throw new Error('Wrong'); }}); }; ajax(3).then(function(){
    console.log('3'); }). Catch (error=>{console.log(error) // error})}Copy the code

4.Promise.all

The promise.all method is used to wrap multiple Promise instances into a new Promise instance.

var p = Promise.all([p1, p2, p3]);
Copy the code

In the code above, the promise. all method takes an array of parameters. P1, P2, and p3 are all Promise instances. If they are not, the Promise. (The promise. all method can take arguments that are not arrays, but must have an Iterator interface and return each member as a Promise instance.)

The state of P is determined by P1, P2 and P3, which can be divided into two cases.

(1) Only when the states of P1, P2 and P3 become depressing, the state of P will become depressing. At this time, the return values of P1, P2 and P3 will form an array and be passed to the callback function of P.

(2) As long as p1, P2 and P3 are rejected, P becomes rejected, and the return value of the first rejected instance is passed to p’s callback function.

{
  function loadImg(src){
    return new Promise((resolve, reject) => {
      let img = document.createElement('img');
      img.src=src;
      img.onload = function(){
        resolve(img);
      }
      img.onerror = function(error){ reject(error); }}); }function showImgs(imgs){
    imgs.forEach(function(img){
      document.body.appendChild(img);
    })
  }
  Promise.all([
    loadImg(' '),
    loadImg(' '),
    loadImg(' '),
  ]).then(showImgs)
}
Copy the code

4.Promise.race

The promise.race method also wraps multiple Promise instances into a new Promise instance.

var p = Promise.race([p1, p2, p3]);
Copy the code

In the above code, the state of P changes as long as one of the first instances of P1, P2, and P3 changes state. The return value of the first changed Promise instance is passed to p’s callback. The parameters of the promise.race method are the same as those of the promise.all method. If it is not a Promise instance, the promise.resolve method, described below, is first called to convert the parameters to a Promise instance, and then further processing. Here’s an example that changes the state of a Promise to Reject if no results are available within a specified time, or resolve otherwise.

{
  function loadImg(src){
    return new Promise((resolve, reject) => {
      let img = document.createElement('img');
      img.src=src;
      img.onload = function(){
        resolve(img);
      }
      img.onerror = function(error){ reject(error); }}); }function showImg(img){
    let img = document.createElement('p');
    p.appendChild(img);
    document.body.appendChild(p);
  }

  Promise.race([
    loadImg(' '),
    loadImg(' '),
    loadImg(' '),
  ]).then(showImgs)
}
Copy the code

Iterator and for… Of circulation

The purpose of the Iterator interface is to provide a unified access mechanism for all data structures. Of circulation. When using the for… When the of loop iterates over some data structure, the loop automatically looks for the Iterator interface. A data structure is said to be “iterable” whenever the Iterator interface is deployed. ES6 states that the default Iterator interface is deployed in the symbol. Iterator property of a data structure, or that a data structure can be considered “iterable” as long as it has the symbol. Iterator property. The symbol. iterator property is itself a function that is the default traverser generator for the current data structure. Executing this function returns a traverser. Iterator is an expression that returns the iterator property of the Symbol object, which is a predefined special value of type Symbol, so it is enclosed in square brackets.

1. The Symbol. Iterator property of the array

The arR variable is an array with a native iterator interface deployed on top of the Symbol. Iterator property of the ARR. So, by calling this property, you get the traverser object.

{
  let arr = ['hellow'.'world'];
  let map = arr[Symbol.iterator]();
  console.log(map.next());  //{value: "hellow".done: false}
  console.log(map.next());  //{value: "world".done: false}
  console.log(map.next());  //{value: "undefined".done: false}}Copy the code

2. User-defined Iterator interfaces

{
  letObj = {start: [31] 1, end:,8,9 [7], [Symbol. The iterator] () {let self = this;
      let index = 0;
      let arr = self.start.concat(self.end);
      let len = arr.length;
      return {
        next() {if(index<len){
            return {
              value:arr[index++],
              done:false}}else{
            return {
              value:arr[index++],
              done:true
            }
          }
        }
      }
    }
  }
  for(letkey of obj){ console.log(key); //1 3 2 7 8 9}}Copy the code

Fifteen Genertor

1. Basic concepts

Generator functions can be understood in many ways. Syntactically, the Generator function is a state machine that encapsulates multiple internal states. Execution of Generator returns an traverser object, that is, Generator is also a traverser object Generator in addition to the state machine. A traverser object that iterates through each state within the Generator in turn. Formally, a Generator function is an ordinary function, but has two characteristics. There is an asterisk between the function keyword and the function name. Second, inside the function body, yield expressions are used to define different internal states (yield means “output” in English).

{
  let tell = function* (){
    yield 'a';
    yield 'b';
    return 'c';
  }
  let k = tell();
  console.log(k.next()); //{value: "a".done: false}
  console.log(k.next()); //{value: "b".done: false}
  console.log(k.next()); //{value: "c".done: true}
  console.log(k.next()); //{value: undefined, done: true}}Copy the code

2. Relationship with the Iterator interface

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 = {};
  obj[Symbol.iterator] = function* (){
    yield '1';
    yield '2';
    yield '3';
  }
  for(letvalue of obj){ console.log(value); // 1 2 3}}Copy the code

3. The next method

{
  let state = function* (){
      yield 'a';
      yield 'b';
      yield 'c';
  }
  let status = state();
  console.log(status.next());  //a
  console.log(status.next());  //b
  console.log(status.next());  //c
  console.log(status.next());  //a
  console.log(status.next());  //b
  console.log(status.next());  //c
  console.log(status.next());  //a
}
Copy the code

4. Simple application of Genertor

// simple lottery {let draw = function(count) {the console. The info (` remaining${count}Time `); }let chou = function *(count){
    while(count>0) { count--; yield draw(count); }}let start = chou(5);
  let btn = document.createElement('button');
  btn.id = 'start';
  btn.textContent = 'lottery';
  document.body.appendChild(btn);
  document.getElementById('start').addEventListener('click'.function(){
    start.next();
  },false); } // long polling {let ajax = function* (){
    yield new Promise((resolve, reject) => {
      setTimeout(function(){
        resolve({code:1})
      },200)
    });
  }
  let pull = function() {let generator = ajax();
    let step = generator.next();
    step.value.then(function(d){
      if(d.code ! = 0) {setTimeout(function(){
          console.log('wait'); // Output every secondwaitpull(); }}, 1000)else{
        console.log(d);
      }
    })
  }
  pull();
}
Copy the code

Xvi modifier

1. Method modification

A decorator function can take three arguments in total. The first argument is the target object to be modified, an instance of the class (as opposed to the class modifier, in which case the target argument refers to the class itself). The second argument is the name of the property to be decorated, and the third argument is the description object of the property.

{
  let readonly = function(target,name,descriptor){
    descriptor.writable = false;
    return descriptor;
  };
  class test{@readonly
    time() {return '2017-08-27'}}let tests = new test(a); console.log(tests.time()); / / / / 2017-08-27let testss = new test(a); // // tests.time =function(){
  // //   console.log('2017-08-28');
  // // }
  // console.log(tests.time());  //Cannot assign to read only property 'time' of object
}
Copy the code

2. Class modification

A modifier is a function that processes a class. The first argument to the decorator function is the target class to be modified.

{
  let typename = function(target,name,descriptor){
    target.myname = 'hello';
  };
  @typename
  class test{

  }

  console.log(test.myname) // hello
}
Copy the code

Xvii Modularization

An ES6 module is not an object. Instead, it explicitly specifies the output code through the export command, which is then input through the import command.

{
  export let A = 123;
  export function text(){
    console.log('123');
  }
  export class hello{
    text(){
      console.log('345'); }}} {let A = 123;
  function text(){
    console.log('123');
  }
  class hello{
    text(){
      console.log('345'); }}export default {
    A,
    text,
    hello
  }
}
Copy the code

Ruan yifeng’s introduction to ECMAScript 6