Wechat official account: [Cat twelve daily], welcome to leave a message and point out question A

Let and const commands

Let: It declares variables that are valid only within this code block

for (let i = 0; i < 10; i++) {}
	console.log(i);
	//ReferenceError: i is not define
Copy the code

Another special aspect of the for loop is that the statement part of the loop is a parent scope, while the body of the loop is a separate child scope

for (let i = 0; i < 3; i++) {
	  let i = 'abc';
	  console.log(i);
	}
	// abc
	// abc
	// abc
Copy the code

There is no variable promotion let. The variable declared must be used after the declaration, or an error will be reported.

// var case
	console.log(foo); / / output is undefined
	var foo = 2;
	
	// let
	console.log(bar); / / error ReferenceError
	let bar = 2;
Copy the code

Temporal dead zone (TDZ) : As long as a let command exists in a block-level scope, its declared variables are “bound” to the zone, no longer subject to external influence, and are no longer safe operations for TypeOF

var tmp = 123;
	if (true) {
	  tmp = 'abc'; // ReferenceError
	  let tmp;
	}
	
typeof x; // ReferenceError
let x;
Copy the code

Duplicate declarations are not allowed

/ / an errorfunction () {
	  leta = 10; var a = 1; } / / an errorfunction () {
	  let a = 10;
	  let a = 1;
	}
Copy the code

Const command

Const declares a read-only constant. Once declared, the value of a constant cannot be changed.

const PI = 3.1415;
PI / / 3.1415

PI = 3;
// TypeError: Assignment to constant variable.
Copy the code

Const has the same scope as the let command: it is only valid in the block-level scope in which the declaration is made.

if (true) {
  const MAX = 5;
}

MAX // Uncaught ReferenceError: MAX is not defined
Copy the code

Constants declared by the const command are also non-promoted and have temporary dead zones that can only be used after the declared position.

if (true) {
  console.log(MAX); // ReferenceError
  const MAX = 5;
}
Copy the code

Essence: In fact, the guarantee is not that the value of a variable cannot be changed, but that 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 in the case of composite types (mainly objects and arrays), the const pointer is guaranteed to be fixed, and the data structure it points to is mutable. Therefore, declaring an object as a constant must be done with great care.

const foo = {}; // Add an attribute to foo, which succeeds foo.prop = 123; Foo. Prop // 123 // Pointing foo to another object will result in an error foo = {}; // TypeError:"foo" is read-only
Copy the code
const a = [];
a.push('Hello'); / / the executable
a.length = 0;    / / the executable
a = ['Dave'];    / / an error
Copy the code

If you really want to freeze an Object, you should use the object. freeze method.

const foo = Object.freeze({});

// In normal mode, the following line does not work;
// In strict mode, this line will report an error
foo.prop = 123;
Copy the code

ES6 six ways to declare variables

ES5 has only two methods for declaring variables: the var command and the function command. In addition to the let and const commands, ES6 has two other ways to declare variables, the import command and the class command, as discussed in a later section. So there are six ways to declare variables in ES6.

Destruct assignment of arrays

ES6 allows you to extract values from arrays and objects and assign values to variables in a pattern called Destructuring. This is “pattern matching,” and as long as the pattern on both sides of the equal sign is the same, the variable on the left is assigned the corresponding value

Es5 writinglet a = 1;
	let b = 2;
	let c = 3;
Copy the code
Es6 writinglet [a, b, c] = [1.2.3];
let [foo, [[bar], baz]] = [1The [[2].3]];
foo / / 1
bar / / 2
baz / / 3

let [ , , third] = ["foo"."bar"."baz"];
third // "baz"

let [x, , y] = [1.2.3];
x / / 1
y / / 3

let [head, ...tail] = [1.2.3.4];
head / / 1
tail / / [2, 3, 4]

let [x, y, ...z] = ['a'];
x // "a"
y // undefined // failed, the value of the variable is equal to undefined
z / / []
Copy the code

Incomplete deconstruction: the pattern to the left of the equals sign matches only part of the array to the right of the equals sign

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

let [a, [b], d] = [1[2.3].4];
a / / 1
b / / 2
d / / 4
Copy the code

The main premise of deconstruction is that you must have default values for the Iterator interface: deconstruction assignments allow you to specify default values

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

let [x, y = 'b'] = ['a']; // x='a', y='b'
let [x, y = 'b'] = ['a'.undefined]; // x='a', y='b'
//ES6 internally uses the strict equality operator (===) to determine whether a position has a value. Therefore, if an array member is not strictly equal to undefined, the default value will not take effect
let [x = 1] = [undefined];
x / / 1

let [x = 1] = [null];
x // null
Copy the code

Object destructuring assignment

Object deconstruction differs from arrays in one important way. The elements of an array are arranged in order, and the value of a variable is determined by its position. The attributes of an object have no order, and variables must have the same name as the attributes to get the correct value

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

let { baz } = { foo: "aaa".bar: "bbb" };
baz // undefined
Copy the code

The variable name does not match the attribute name and must be written as follows

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'
let { foo: baz } = { foo: "aaa".bar: "bbb" };
baz // "aaa"
foo // error: foo is not defined
//foo is the matching pattern and baz is the variable. It is the variable baz that is actually assigned, not the pattern foo.
Copy the code

In this way, variables are declared and assigned together. For lets and const, variables cannot be redeclared, so an error is reported if the assigned variable has been declared before.

let foo;
let {foo} = {foo: 1}; // SyntaxError: Duplicate declaration "foo"

let baz;
let {bar: baz} = {bar: 1}; // SyntaxError: Duplicate declaration "baz"
// The parentheses on the line below the let command are required, otherwise an error will be reported. Because the parser interprets the opening brace as a block of code, not an assignment statement.
let foo;
({foo} = {foo: 1}); / / success

let baz;
({bar: baz} = {bar: 1}); / / success
Copy the code

The deconstruction of an object can also specify default values. The property value of the object is strictly equal to undefined

var {x = 3} = {};
x / / 3

var {x, y = 5} = {x: 1};
x / / 1
y / / 5

var {x:y = 3} = {};
y / / 3

var {x:y = 3} = {x: 5};
y / / 5

var { message: msg = 'Something went wrong' } = {};
msg // "Something went wrong"
Copy the code

You can assign values to existing objects

let { log, sin, cos } = Math;
// The logarithm, sine, and cosine methods of the Math object are assigned to the corresponding variables to make it easier to use.
Copy the code

Arrays are special objects in nature, so they can be deconstructed into object properties

let arr = [1.2.3];
let {0 : first, [arr.length - 1] : last} = arr;
first / / 1
last / / 3
Copy the code

Destruct assignment of a string

Strings can also deconstruct assignments. This is because at this point, the string is converted to an array-like object.

const [a, b, c, d, e] = 'hello';
a // "h"
b // "e"
c // "l"
d // "l"
e // "o"
Copy the code
Array-like objects have a length attribute, so you can also deconstruct and assign to this attribute.Copy the code
let {length : len} = 'hello';
len / / 5
Copy the code

Deconstructive assignment of values and Bores

When deconstructing an assignment, if the value and Boolean are to the right of the equals sign, the object is converted first

let {toString: s} = 123;
s === Number.prototype.toString // true

let {toString: s} = true;
s === Boolean.prototype.toString // true
Copy the code

As long as the value to the right of the equals sign is not an object or array, it is first converted to an object. Undefined and NULL cannot be converted to objects, so destructuring assignments to them will result in an error.

let { prop: x } = undefined; // TypeError
let { prop: y } = null; // TypeError
Copy the code

Destruct assignment of function arguments

Function arguments can also be destructively assigned

function add([x, y]){
  return x + y;
}

add([1.2]); / / 3

[[1.2], [3.4]].map(([a, b]) = > a + b);
// [3, 7]
Copy the code

Function arguments can also be destructed using default values

function move({x = 0, y = 0} = {}) {
  return [x, y];
}

move({x: 3.y: 8}); / / [3, 8]
move({x: 3}); / / [3, 0]
move({}); / / [0, 0]
move(); / / [0, 0]If you write it differently, you get different resultsfunction move({x, y} = { x: 0, y: 0 }) {
  return [x, y];
}

move({x: 3.y: 8}); / / [3, 8]
move({x: 3}); // [3, undefined]
move({}); // [undefined, undefined]
move(); / / [0, 0]
Copy the code

Parenthesis problem

While deconstructing assignments is convenient, it’s not easy to parse. There is no way for the compiler to know from the start whether an expression is a pattern or an expression. It must be parsed to (or not) the equals sign. This raises the question of what to do if parentheses are present in the schema. The rule of ES6 is that parentheses should not be used whenever there is a possibility of ambiguity about deconstruction. However, this rule is actually not so easy to discern and can be quite troublesome to deal with. Therefore, it is recommended that parentheses not be placed in schemas whenever possible. A variable declaration statement must not contain parentheses.

// All errors: because they are variable declarations, the schema cannot use parentheses
let [(a)] = [1];

let {x: (c)} = {};
let ({x: c}) = {};
let {(x: c)} = {};
let {(x): c} = {};

let { o: ({ p: p }) } = { o: { p: 2}};Copy the code

The schema must not have parentheses in function arguments, which are also variable declarations

/ / an error
function f([(z)]) { return z; }
Copy the code

An assignment statement cannot enclose an entire pattern, or a layer within a nested pattern, within parentheses.

{p: a}) = {p: 42}; ([a]) = [5]; [({ p: a }), { x: c }] = [{}, {}];Copy the code

A case where parentheses can be used

[(b)] = [3]; / / right
({ p: (d) } = {}); / / right
[(parseInt.prop)] = [3]; / / right
// All three lines above execute correctly because they are assignment statements, not declaration statements; Second, their parentheses are not part of the schema. In the first line, the schema takes the first member of the array, regardless of parentheses; In the second line, the mode is P, not D; The third line of statements has the same properties as the first.
Copy the code

use

(1) Exchange the values of variables

let x = 1;
let y = 2;

[x, y] = [y, x];
Copy the code

(2) Return multiple values from a function: a function can return only one value. If you want to return multiple values, you can only return them in an array or an object. With deconstructing assignments, it’s very convenient to pull out these values

// Return an array

function example() {
  return [1.2.3];
}
let [a, b, c] = example();

// Return an object

function example() {
  return {
    foo: 1.bar: 2
  };
}
let { foo, bar } = example();
Copy the code

(3) Definition of function parameters: Destructuring assignments makes it easy to map a set of parameters to variable names.

// Arguments are an ordered set of values
function f([x, y, z]) {... } f([1.2.3]);

// Arguments are an unordered set of values
function f({x, y, z}) {... } f({z: 3.y: 2.x: 1});
Copy the code

(4) Extracting JSON data: Deconstructing assignment is especially useful for extracting data from JSON objects

let jsonData = {
	  id: 42.status: "OK".data: [867.5309]};let { id, status, data: number } = jsonData;
	
	console.log(id, status, number);
	// 42, "OK", [867, 5309]
Copy the code

(5) Default values of function parameters

jQuery.ajax = function (url, {
  async = true,
  beforeSend = function () {},
  cache = true,
  complete = function () {},
  crossDomain = false.global = true.//. more config }) {
  // ... do stuff
};
/ / the default value of the specified argument, avoids the within the function body to write var foo = config. The foo | | 'default foo'; Such a statement
Copy the code

Iterator: Iterator: Iterator: Iterator: Iterator: Iterator: Iterator: Iterator: Iterator: Iterator: Iterator: Iterator The of loop traverses. The Map structure natively supports the Iterator interface, and it is very convenient to obtain key names and values along with the deconstructive assignment of variables.

var map = new Map(a); map.set('first'.'hello');
map.set('second'.'world');

for (let [key, value] of map) {
  console.log(key + " is " + value);
}
// first is hello
// second is world
Copy the code

An array of

Es6 adds some new array features, as well as improved old ones

Always pass an element of the array

let items = Array.of(20); console.log(items.length) //1 console.log(items[0]) //20 itmes = Array.of(2); console.log(itmes.length); //1 console.log(itmes[0]); //2 itmes = Array.of('2'); console.log(itmes.length); //1 console.log(itmes[0]); / / '2'Copy the code

How to convert a class object into an array

Function translate(){return array. from(arguments)} let number = translate(1,3,4,5); console.log(number); //[1, 3, 4, 5]Copy the code

Mapping conversion (conversion of the second parameter)

Function translate(){return array. from(value,(value) => value+1)} let number = translate(1,3,4,5); console.log(number); //[2, 4, 5, 6]Copy the code

The third value is this

let helper = { diff:1, add(value){ return value+this.diff; }} function translate () {return Array. The from (the arguments, the helper. Add, helper)} let number = translate 5-tetrafluorobenzoic (1); console.log(number); // [2, 4, 5, 6]Copy the code

Array.from can be used to convert iterables

let number = { *[Symbol.iterator](){ yield 1; yield 2; yield 3; yield 4; } } let number2 = Array.from(number,(value) => value+1); console.log(number2); //[2, 3, 4, 5]Copy the code

New methods find() and findIndex()

A function of both methods takes a callback function and a this as an argument

Find returns a value whose return is true

Let Numbers =,34,4,44,33,56 [1]; console.log(numbers.find((item,index,arr) => { if(item>33){ console.log(item,index,arr); //34 1 [ 1, 34, 4, 44, 33, 56 ] return item } })) //34Copy the code

FindIndex () returns the position of a value that satisfies true (the first one)

Let Numbers =,34,4,44,33,56 [1]; console.log(numbers.findIndex((item,index,arr) => { if(item>33){ console.log(item,index,arr); //34 1 [ 1, 34, 4, 44, 33, 56 ] return item } })) //1Copy the code

The fill() method fills all elements of an array from the start index to the end index with a fixed value

It takes three parameters: the value to fill, the start of the fill, and the end of the knot

Let Numbers =,34,4,44,33,56 [1]; console.log(numbers.fill(1)) //[ 1, 1, 1, 1, 1, 1 ] console.log(numbers) //[ 1, 1, 1, 1, 1, 1] / / change the original array let nums =,3,4,5,2,4,3 [2] the console. The log (nums. The fill (1, 2)) / / [2, 3, 1, 1, 1, 1, 1] console. The log (nums. The fill,2,5 (6)); //[2, 3, 6, 6, 6, 1, 1Copy the code

The copyWith method shallowly copies part of an array to another location in the same array and returns it without changing its size

The method takes three values, one for the position to start filling, one for the position to start copying, changing the original array, and one for the position to end copying

Let Numbers =,34,4,44,33,56 [1]; The console. The log (Numbers. CopyWithin (2, 3)); //[1, 34, 44, 33, 56, 56] console.log(numbers. CopyWithin (2,0,1)); //[1, 34, 1, 33, 56, 56]Copy the code

Finalize the design array

Stereotype arrays are specialized arrays for handling numeric (as the name implies, not all types) data. They were first used in WebGL, a port of OpenGL ES 2.0, to render them in Web pages using canvas tag elements. Stereotype arrays have also been ported to provide fast bitwise operations for JS

In JS, numbers are stored in 64-bit floating point format and converted to 32-bit integers on demand, so the arithmetic is too slow to meet WebGL’s requirements. Stereotyped arrays were introduced in ES6 to solve this problem and provide higher performance arithmetic operations. The so-called stereotyped array is to convert any number into an array containing numeric bits, which can then be further processed through the familiar JS array method

Array buffer

The ArrayBuffer object is used to represent a generic, fixed-length buffer of raw binary data. An ArrayBuffer does not operate directly, but through a type array object or DataView object, which represents the data in the buffer in specific formats and reads and writes the contents of the buffer in those formats.

let buffer = new ArrayBuffer(10); console.log(buffer.byteLength); //10 // let buffer2 = buffer.slice(1,3); console.log(buffer2.byteLength) //2Copy the code

You cannot change the size of the cache, only the data in the data buffer

Manipulate array buffers through views

An array buffer is an address in memory, and a view is an interface to manipulate memory. A view can manipulate an array buffer or a subset of buffer bytes and read and write data according to one of the numeric data types. The DataView type is a generic array buffer view that supports all eight numeric data types

  • Signed 8-bit integer (int8)
  • Unsigned 8-bit integer (uint8)
  • Signed 16-bit integer (int16)
  • Unsigned 16-bit integer (uint16)
  • Signed 32-bit integer (int32)
  • Unsigned 32-bit integer (uint32)
  • 32-bit floating point number (float32)
  • 64-bit floating-point number (float64)

You can obtain information about a view through the following read-only properties

  • Buffer The array buffer bound to the view
  • The second argument to the byteOffset DataView constructor, which defaults to 0 and has a value only when the argument is passed in
  • The third argument to the byteLength DataView constructor is byteLength, the length of the buffer, by default
Let buffer = new ArrayBuffer(10), view1 = new DataView(buffer), view2 = new DataView(buffer,5,2); // The first argument is the buffer created, the second argument is the start position of the operation buffer, and the third argument is the length of the buffer console.log(view1.buffer === buffer); //true console.log(view2.buffer === buffer); //true console.log(view1.byteOffset); //0 console.log(view2.byteOffset); //5 console.log(view1.byteLength); //10 console.log(view2.byteLength); / / 2Copy the code

Read and write data

Js 8 numeric data types can be found on the DataView prototype

  • Reading method DataView. Prototype. GetInt8 () from the DataView starting position for byte count of the specified offset (byteOffset) obtain an 8-bit number (one byte). DataView. Prototype. GetUint8 () From the DataView starting position for byte count at the specified offset (byteOffset) for a number of 8-bit bytes (unsigned). The DataView. Prototype. GetInt16 () From the DataView starting position for byte count at the specified offset (byteOffset) for a number of 16 – bit (short integer). DataView. Prototype. GetUint16 () From the DataView starting position for byte count at the specified offset (byteOffset) for a number of 16 – bit short (unsigned integer) DataView. Prototype. GetInt32 () From the DataView starting position for byte count at the specified offset (byteOffset) get a 32 – bit number (long). DataView. Prototype. GetUint32 () From the DataView starting position for byte count at the specified offset (byteOffset) get a 32 – bit number (unsigned long integer) DataView. Prototype. GetFloat32 () From the DataView starting position for byte count at the specified offset (byteOffset) get a 32 – bit number (float). DataView. Prototype. GetFloat64 () Gets a 64-bit number (a double-precision floating-point number) from the specified byteOffset at the DataView starting position.
  • Write method DataView. Prototype. SetInt8 () from the DataView starting position for byte count at the specified offset (byteOffset) to store a number of 8-bit (one byte). DataView. Prototype. SetUint8 () From the DataView starting position for byte count at the specified offset (byteOffset) to store a number of 8-bit bytes (unsigned). The DataView. Prototype. SetInt16 () From the DataView starting position for byte count at the specified offset (byteOffset) to store a number of 16 – bit short (integer). DataView. Prototype. SetUint16 () From the DataView starting position for byte count at the specified offset (byteOffset) to store a number of 16 – bit short (unsigned integer) DataView. Prototype. SetInt32 () From the DataView starting position for byte count at the specified offset (byteOffset) to store a 32 – bit number (long). DataView. Prototype. SetUint32 () From the DataView starting position for byte count at the specified offset (byteOffset) to store a 32 – bit number (unsigned long integer) DataView. Prototype. SetFloat32 () From the DataView starting position for byte count at the specified offset (byteOffset) to store a 32 – bit number (float). DataView. Prototype. SetFloat64 () Stores a 64-bit number (a double-precision floating-point number) at the specified byte offset from the DataView starting position.
  • usage
Let buffer = new ArrayBuffer(10), // Create view instance with DataView view = new DataView(buffer); The setInt8 (0, 5); view.setInt8(1,-1); console.log(view.getInt8(0)); //5 console.log(view.getInt8(1)); Console. log(view.getint16 ()) //1535; //-1 // can also be called with getInt16 bytes, which combine two 8-bit characters into a single 16-bit characterCopy the code

Stereotype array – Special view type

The buffer type view above can be varied at will, but we only want to deal with one data type, which makes it easy to choose and judge

View1 = new Int8Array(buffer), view2 = new Int8Array(buffer,5,2); let buffer = new ArrayBuffer(buffer,5,2); // The first argument is the buffer created, the second argument is the start position of the operation buffer, and the third argument is the length of the buffer console.log(view1.buffer === buffer); //true console.log(view2.buffer === buffer); //true console.log(view1.byteOffset); //0 console.log(view2.byteOffset); //5 console.log(view1.byteLength); //10 console.log(view2.byteLength); / / 2Copy the code

Instead of creating an array buffer, create a stereotyped array

let ints = new Int16Array(2), floats = new Float32Array(5); console.log(ints.byteLength); //4 console.log(ints.length); //2 console.log(floats.byteLength); //20 console.log(floats.length); / / 5Copy the code

You cannot use the cache without passing a value to the stereotype parameter because its capacity defaults to 0

The third way to create a stereotyped array is to call the constructor and pass in any of the following objects as the only arguments

1. A stereotype array

Each element in the array is copied as a new element into the new stereotype array. For example, if an INT8 array is passed into the Int16Array constructor, the value of int8 is copied into a new INT16 array that uses the new array buffer

2. An iterable

Object’s iterator is called to select the elements to be inserted into the stereotype array by retrieving all items. If all elements are invalid types that do not apply to the view type, the constructor will throw an error

3. An array

The elements of the array are copied to a new stereotype array, and the constructor throws an error if all the elements are invalid types that do not apply to the view type

4. An array-like object

The same behavior as passing an array

let int1 = new Int16Array([15.25]),
int2 = new Int32Array(int1);
    
console.log(int1.buffer === int2.buffer); / / 4
console.log(int1.byteLength);   / / 15
console.log(int1[0])    / / 25
console.log(int1[1])    / / 8
console.log(int2.byteLength)    / / 2
console.log(int2.length)    / / 15

console.log(int2[0]);   / / 15
console.log(int2[1]);   / / 25
Copy the code

The element size

Each stereotype array consists of multiple elements, the element size, which refers to the number of bytes represented by each element, stored in the BYTES_PRE_ELEMENT property of each constructor and each instance

console.log(UInt8Array.BYTES_PRE_ELEMENT);
console.log(UInt16Array.BYTES_PRE_ELEMENT);

let ints = new Int8Array(5);
console.log(ints.BYTES_PER_ELEMENT);
    
Copy the code

Stereotyped arrays also apply to the generic methods of arrays, but there are differences

// The prototype is different
let ints = new Int16Array([20.50]);
console.log(ints instanceof Array); //false
console.log(Array.isArray(ints));  //false
// The size of the array elements is the same and cannot be expanded
let ints = new Int16Array([25.50]);
console.log(ints.length); / / 2
console.log(ints[0]); / / 25
console.log(ints[1]); / / 50

ints[2] = 5; 

console.log(ints.length); / / 2
console.log(ints[0]); / / 25
//0 is used to replace all invalid values
let ints = new Int16Array(['hi']);
console.log(ints.length); / / 1
console.log(ints[0]);   / / 0
Copy the code

Missing method

  • concat()
  • shift()
  • pop()
  • splice()
  • push()
  • unshift()

Additional methods

  • Set (): Copies other arrays into an existing stereotype array
  • Subarray (): Extracts part of the existing stereotype array as a new stereotype array

Set () is an array (stereotyped or normal) and an optional offset representing the starting point of insertion,

let ints = new Int16Array(4); Ints. Set ([25, 50]); Ints. Set ([125, 50], 1); console.log(ints.toString()); / / 25,50,75,0Copy the code

SubArray () one for an optional start position and one for an optional end

Let ints = new Int16Array([25,50,75,100]), subint1 = ints.subarray(), subint2 = ints.subarray(2), Subint3 = ints. Subarray (1, 3); console.log(subint1.toString()); / / 25,50,75,100 console. The log (subint2. ToString ()); / / 75100. The console log (subint3. ToString ()); / / 75100Copy the code

If you think my article is ok, click a like or follow the next, there are wonderful stories waiting for you oh, but also can cloud masturbation cat