ES2015 (ES6)
ES2015 is the 6th version of the ECMA Script(JS) language released in 2015, so it is also called ES6. Since then, ECMA Script has released a large version each year adding important features, which we call ES6+.
This paper mainly summarizes the main features of ES2015-ES2019, a learning front-end children’s shoes should be commonly used and understand some of the features.
The main roles of ES2015:
- Solve some shortcomings of the original grammar
- Enhance the existing syntax
-
New objects, new methods, new functions
Promise, Proxy, Object.Assign, etc
-
New data types and data structures
Symbol, Set, Map, etc
ES2015 common environment support
- Nodejs query: https://node.green/
- The browser query: http://kangax.github.io/compat-table/es6/
PC browser support for ES2015
- Chrome: 51 will now support 97% of the new ES6 features.
- Firefox: Version 53 now supports 97% of the new ES6 features.
- Safari: Version 10 will support 99% of the new ES6 features.
- Edge: Edge 15 supports 96% of ES6’s new features. Edge 14 supports 93% of ES6’s new features.
- IE: ES6 is not supported by IE7 ~ 11
Mobile browser support for ES2015
- IOS: Version 10.0 will support 99% of the new ES6 features.
- Android: Little support for ES6 new features (5.1 only supports 25%)
Server support for ES2015, specifically see:https://node.green/
- Node.js: 97% of ES6’s new features are supported as of version 6.5. (6.0 supports 92%)
Var (let, const)
- There are only global scopes, function scopes, and no strict block-level scopes
- Existence variable lifting
- Variables can be declared and defined separately
- Variables can be repeatedly declared
Let (block-level scope)
- There is block-level scope
- Invariable lift
- Variables can be declared and defined separately
- Variables cannot be repeatedly declared
Const constants
- There is block-level scope
- Invariable lift
- Variables must be declared and defined in the same statement
- Variables cannot be repeatedly declared
- Cannot change the value of a declared variable (for example, you can change the value of an object’s property, but you cannot change the object’s address)
- Best practice: Use const instead of var and let instead
An array of deconstruction
const [foo, bar, baz] = arr console.log(foo, bar, baz) const [, , Baz] = arr console.log(baz) // Decorstruct the remaining array elements // Only use the extended operator const [foo,...rest] = arr console.log(rest) // Decorstruct less elements, Const [foo] = arr console.log(foo) // Default value is set to const [foo, bar, baz = 123, more = 'default value'] = arr console.log(bar, more)
Object to deconstruct
Const obj = {name: 'zce', age: 18} // When the variable name is repeated, you can rename and set the default value const name = 'Tom' const {name: objName = 'jack' } = obj console.log(objName)
Template string
- Support for newline characters
- Support for embedded variables, expressions
Const name = 'Tom' // You can insert an expression with ${}, Const MSG = 'hey, ${name} -- ${1 + 2} ---- ${Math.random()}' console.log(MSG)
String extension method
- Includes strings
- Whether startsWith begins with a string
- Whether endsWith endsWith a string
const message = 'Error: foo is not defined.'
console.log(
// message.startsWith('Error')
// message.endsWith('.')
message.includes('foo')
)
Default values for the arguments to the method
- Use = after the function parameter to set the default value
- Default values are set only if the parameter is passed as undefined or if no value is passed (false does not).
- If there are only partial defaults, you need to leave the code that sets the defaults later; Otherwise, it cannot be used normally
// The default parameter must be last in the parameter list function foo (bar, enable = true) {console.log(' Foo Invoked - enable: ') console.log(enable) } foo(false)
The remaining parameters of the method
- Appends only in the last bit of a parameter
- You can only use it once
- Args is an array, unlike arguments, which is a pseudo array
function foo (first, ... args) { console.log(args) } foo(1, 2, 3, 4)
An array of
const arr = ['foo', 'bar', 'baz'] // console.log( // arr[0], // arr[1], // arr[2], // ) // console.log.apply(console, arr) console.log(... arr)
Arrow function
Plug-in: Fira Code fonts will make the arrows look better
Filter (function (item) {// return item % 2 //}) const Arr = [1, 2, 3, 4, 5, 6, 7] // Arr. Filter (function (item) {// return item % 2 //}) Filter (I => I % 2)
Short for arrow function
Function (value){return value} =>value
The arrow function this points to
- The this of a normal function refers to the object on which its method is called
- The arrow function’s this points to the same point as its outer function’s this. That is, the arrow function does not change the direction of this
// Arrow function and this // Arrow function do not change this to const person = {name: 'Tom ', // sayHi: SayHi () {// console.log(' hi, my name is ${this.name} ')// Tom, this refers to the caller //} sayHi: () => {console.log(' hi, my name is ${this.name} ') //undefined, this and sayHi() outside this function this is the same}, sayHiAsync: Function () {// const _this = this // setTimeout(function () {// console.log(_this.name) // This is the window. _this //}, 1000) console.log(this) setTimeout(() => {// console.log(this.name) // This refers to this in SayHiasync, Person console.log(this)}, 1000)}} person.sayHi() person.sayHiAsync()
Object literals
- If the attribute name and the value variable name are the same, you can omit a variable
- Method shorthand: You can omit the “: function”
- Evaluate attribute names: attribute names can use any expression in []
Const bar = '345' const obj = {foo: 123, // bar: bar // The attribute name is the same as the variable name, so you can omit: bar bar, // method1: Function () {// console.log('method111') //} Function method1 () {console.log('method111') // This is just a normal function. This points to obj. Console. log(this)}, // Math.random(): 123 // Not allowed, use [] // Use [] to make the result of the expression the property name [bar]: 123}
Object.assign
Object. Assign is an incomplete deep copy? How many copies did it make?
Unable to get get and set information in obj
- Assigns a value from the source object to the target object
- The target object and the return value are the same object
- If there is a property of the same name in the target object, the property is overridden
- Multiple source objects can be passed in, overwriting the target in sequence
const source1 = { a: 123, b: 123 } const source2 = { b: 789, d: 789 } const target = { a: 456, c: 456} const result = Object.assign(target, source1, source2) console.log(target) console.log(result === = target) //true, The target object and the return value are one object
Object.is
0 == false // => true
0 === false // => false
+0 === -0 // => true
NaN === NaN // => false
Object.is(+0, -0) // => false
Object.is(NaN, NaN) // => true
The Proxy and the Object. DefineProperty
Proxy listens for changes in Object properties
Contrast Object. DefineProperty reference notes: https://gitee.com/ymcdhr/e-task/wikis/?sort_id=4053906
Reflect (Uniform manipulation of Object Object methods)
- The method in Reflect is called by default in the method of Proxy property, for example:
const obj = { foo: '123', bar: '456'} const proxy = new proxy (obj, {get (target, property) {console.log('watch logic~')) // Return reflect. get(target, property)}})
- Relect provides a unified method for manipulating Object objects, and there are 13 complete methods on MDN:
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Reflect
// console.log('name' in obj)
// console.log(delete obj['age'])
// console.log(Object.keys(obj))
console.log(Reflect.has(obj, 'name'))
console.log(Reflect.deleteProperty(obj, 'age'))
console.log(Reflect.ownKeys(obj))
Promise
JS Single Threading Mechanism and Asynchronous Programming (Promise, Generator, Async, Aawait)
The basic syntax for the Class Class
// function Person (name) {// this.name = name //} // person.prototype.say = function () {// console.log(`hi, ${this.name} ') //} class Person {// constructor (name) {this.name = name} // member variable age = 18 say () { console.log(`hi, my name is ${this.name}`) } } const p = new Person('tom') p.say()
Static method in Class
- Declare a static method: static keyword
- Call the static method, Person.say
- The static method’s this points to the class
// static method class Person {constructor (name) {this.name = name} say () {console.log(' hi, '); my name is ${this.name}`) } static create (name) { return new Person(name) } } const tom = Person.create('tom') tom.say()
The Class inheritance
- Using extends inheritance
- Notice the use of super, which gives access to the superclass; Usually used to execute superclass constructors.
class Person { constructor (name) { this.name = name } say () { console.log(`hi, My name is ${this.name} ')}} class Student extends Person {constructor (name, number) {super(name); This. Number = Number} hello () {super.say() // Call parent member console.log(' My school number is ${this.number}`) } } const s = new Student('jack', '100') s.hello()
The Set, the Map
Set A collection of arrays with no duplicate elements
Common member methods
- Add item and return the collection itself, which can be called chained
- S.size Gets the length of Set
- S.hs (item) determines whether an item exists
- .delete(item) Deletes an item
- S.clear () deletes all
const s = new Set() s.add(1).add(2).add(3).add(4).add(2) // console.log(s) // s.forEach(i => console.log(i)) / / forEach, for... Set // for (let I of s) {// console.log(I) //} // console.log(s.size) // console.log(s.hs (100)) // console.log(s.delete(3)) // console.log(s) // s.clear() // console.log(s)
Often used for array deduplication
// Application scenarios: Array to const arr = [1, 2, 1, 3, 4, 1] const result1 = Array. From (new Set(arr)) const result2 = [...new Set(arr)] console.log(result1, result2)
Map is a collection of objects that can use complex structures as properties
When previous objects stored object properties, complex data was converted to a string (toString() method), as follows:
const obj = {}
obj[true] = 'value'
obj[123] = 'value'
obj[{ a: 1 }] = 'value'
console.log(Object.keys(obj))
//0: "123"
//1: "true"
//2: "[object Object]"
Map can be used to store complex data as object properties. The common methods are as follows:
const m = new Map() const tom = { name: 'tom' } m.set(tom, 90) console.log(m) console.log(m. set (Tom)) // m.delete() // m.delete() // m.clear() // forEach can traverse the items in the Map m.forEach((value, key) => { console.log(value, key) })
Symbol
A new, underlying data type, each time created with a unique value
let s = Symbol(); typeof s // "symbol" let s1 = Symbol('foo'); let s2 = Symbol('foo'); Let s3 = Symbol. For ('foo'); let s3 = Symbol. For ('foo'); let s3 = Symbol. let s4 = Symbol.for('foo'); s3 === s4 // true
Can be converted to a string by description (ES2019 method)
let s1 = Symbol('foo'); let s2 = Symbol('foo'); s1 // Symbol(foo) s2 // Symbol(foo) s1 === s2 // false s1.toString() // "Symbol(foo)" s2.toString() // "Symbol(foo)" S1.description // "foo" // method provided by ES2019
Can be used as an object property name to avoid namesake conflicts
const obj = {}
obj[Symbol()] = '123'
obj[Symbol()] = '456'
console.log(obj)
//Symbol(): "123"
//Symbol(): "456"
When defining an attribute using the Symbol value, the Symbol value must be enclosed in square brackets and the dot operator cannot be used
let s = Symbol(); // Let a = {}; a[s] = 'Hello! '; Let a = {[s]: 'Hello! '}; // A [s] // "Hello!"
It can be accessed as a private member of the object, not directly from the outside (because each access is different), but only through the internal this
/ / case 2: Symbol simulation realization of private members / / a. s = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = const name = Symbol () const person = {[name] : 'zce', Say () {the console. The log (this [name])}} / / only exposed person / / b.j s = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = / / because it could not create the same // Person [Symbol()] person.say(); // Person [Symbol()] person.say();
Note: for… In, Obeject. Keys, Json. Stringify cannot use on Symbol: Object. GetOwnPropertySymbols, alternative Obeject. Keys methods used for Symbol
for… Of Unified Traversal Method
Before the for… In traverses key-value pairs, and forEach has limitations
- The traversal can be terminated by using a break. Foreach cannot break out of the loop
- Array arrays, sets, and Map objects can be traversed
- Normal objects cannot be directly for… Of traversal because it does not have the Symbol. Iterator attribute
- The reason that the Iterator interface is not deployed on objects by default is that it is uncertain which property of the Object will be iterated first and which will be iterated later, which needs to be specified manually by the developer.
- All you can do is use for… Objects of are required to have the Symbol. Iterator property
// for... Of loop const arr = [100, 200, 300, 400] // for... ForEach (item => {console.log(item)}) for (const item of arr) {forEach(item => {console.log(item)}) {forEach(item => {console.log(item)}) { Console. log(item) if (item > 100) {break}} // Foreach cannot break out of loop, // arr.some() // arr.every() // Arr.every () // Arr.every () // Arr.every () // Arr.every () // Set is the same const s = new Set(['foo', 'bar']) for (const item of s) {console.log(item)} Const m = new Map() m.set('foo', '123') m.set('bar', '345') for (const [key, value] of m) {console.log(key, key) } // Ordinary objects cannot be directly for... For (const item of obj) {console.log(item)}
Iterable interface Iterator (mainly for… Of use)
- Some prototype objects for data structures proto Contains the Symbol. Iterator method
- The iterator method returns a pointer object with the next() method
- Each time the next() method is executed, it returns the next data
A data structure with a Symbol. Iterator attribute
Array, Map, Set, String, TypeArray, Arguments to functions, NodeList
The iterator traverses like this.
- (1) Create a pointer object that points to the starting position of the current data structure. That is, the traversal object is essentially a pointer object.
- (2) The first time we call the next method of the pointer object, we can point to the first member of the data structure.
- (3) The second time we call the next method of the pointer object, the pointer points to the second member of the data structure.
- (4) Keep calling the next method of the pointer object until it points to the end of the data structure.
Enables objects to use for… of
Const obj = {// (const obj = {// (const obj = {// (const obj = {// (const obj = {//)); // (const obj = {// (const obj = {//)); // (const obj = {//)); Function () {return (Iterator) {return (Iterator) {return (Iterator) {return (Iterator); Function () {// 3, iterationResult, next() return {value: 'zce', done: True}}}}} for (const item of obj) {console.log(' body of loop ', item)}
Enables objects to use for… Of, complete code
const obj = { store: ['foo', 'bar', 'baz'], [Symbol.iterator]: function () { let index = 0 const self = this return { next: function () { const result = { value: self.store[index], done: Return result}}}} for (const item of obj) {console.log(' item ', item)}
Iterator pattern (one of the design patterns)
Another major use of iterators is the iterator pattern
Gernator generator
Reference: JS Single Threading Mechanism and Asynchronous Programming (Promise, Generator, Async, Aawait)
ES Modules
Refer: ES Modules/CommonJS/AMD/CMD in Engineering
New features in ES2016
The array includes method
// Array.prototype.includes ----------------------------------- const arr = ['foo', 1, NaN, False] // Found return element index console.log(arr.indexOf('foo')) // Found return -1 console.log(arr.indexOf('bar')) // Unable to find NaN in array Console. log(arr.indexOf(NaN)) // Directly returns if the specified element exists console.log(arr.indexOf('foo')) // Can find NaN console.log(arr.includes(NaN))
Exponential operator
/ / index operator -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - the console. The log (2, 10)) (math.h pow console. The log (2 * 10)
New features in ES2017
Object new method
Object.values — similar to Object.keys, returns an array of Object values. Object.entries — returns an array of key-value pairs in an Object, combined with for… Of can traverse obj
const obj = { foo: 'value1', bar: 'value2' } // Object.values ----------------------------------------------------------- console.log(Object.values(obj)) // Object.entries ---------------------------------------------------------- console.log(Object.entries(obj)) // It is simpler than Iterator, simply converting obj to an array first, and then using for... of for (const [key, value] of Object.entries(obj)) { console.log(key, value) } console.log(new Map(Object.entries(obj)))
Object. GetOwnPropertyDescriptors — — to get complete information on the attributes of the Object, the main use Object. The ES5 the get and set the assign for less than the set and get information
const p1 = {
firstName: 'Lei',
lastName: 'Wang',
get fullName () {
return this.firstName + ' ' + this.lastName
}
}
// console.log(p1.fullName)
// const p2 = Object.assign({}, p1)
// p2.firstName = 'zce'
// console.log(p2)
const descriptors = Object.getOwnPropertyDescriptors(p1)
// console.log(descriptors)
const p2 = Object.defineProperties({}, descriptors)
p2.firstName = 'zce'
console.log(p2.fullName)
String new method
String.prototype.padStart / String.prototype.padEnd
const books = {
html: 5,
css: 16,
javascript: 128
}
// for (const [name, count] of Object.entries(books)) {
// console.log(name, count)
// }
for (const [name, count] of Object.entries(books)) {
console.log(`${name.padEnd(16, '-')}|${count.toString().padStart(3, '0')}`)
}
Adds a tail comma to a function argument
const arr = [
100,
200,
300,
400,
]
const arr = [
100,
200,
300
]
Added Async/Await Async programming syntax sugar
References:
ECMA6.0 English specification
From the ES2017 standard; Async and await are more convenient for asynchronous programming and are usually used in pairs;
1, async, await function upgrade relative to generate:
- (1) Built-in actuator
- (2) Better semantics
- (3) Better extender
- (4) The return value is promise
2, return value of async, await
-
(1) async returns a Promise object; But beware:
The async function returns a Promise object.
2. The value returned by the return statement inside the async function becomes the parameter of the callback function of the then method.
async function f() {
return 'hello world';
}
f().then(v => console.log(v))
// "hello world"
- (2) The return value of “await” will vary according to the following parameter. There are two types of “await”;
3, await the parameters after
- (1) await followed by a Promise object; => returns the result of the Promise object;
- (2) await followed by a value; => return this value directly;
4. Error handling methods
If the Promise asynchronous operation following await fails, the Promise object returned by the async function is rejected. It is better to place await command on try… Catch code block
Async function f() {await new Promise(function (resolve, reject) {throw new Error(' Error '); }); } f() .then(v => console.log(v)) .catch(e => console.log(e)) async function myFunction() { try { await somethingThatReturnsAPromise(); } catch (err) { console.log(err); Another writing}} / / async function myFunction () {await somethingThatReturnsAPromise (). The catch (function (err) { console.log(err); }); }
5, Concurrent/cyclic asynchronous request processing
(1) If the asynchronous request is executed serially, it needs to wait synchronously, which will be time-consuming;
let foo = await getFoo(); let bar = await getBar(); // async function dbFuc(db) {let docs = [{}, {}, {}]; for (let doc of docs) { await db.post(doc); }} // 2, wrong serial execution:? According to? Thinking about? Async inside forEach should be async and concurrently executed without await? Function dbFuc(db) {// async let docs = [{}, {}, {}]; Async function (doc) {await db.post(doc); }); }
(2) parallel execution — wait for all responses before executing the next step;
async function dbFuc(db) { let docs = [{}, {}, {}]; let promises = docs.map((doc) => db.post(doc)); let results = await Promise.all(promises); console.log(results); } async function dbFuc(db) {let docs = [{}, {}, {}]; let promises = docs.map((doc) => db.post(doc)); let results = []; for (let promise of promises) { results.push(await promise); } console.log(results); }
(3) parallel execution — do not wait for all the responses, a callback one back;
// Do not await inside for; Also don't write serial callbacks; // Write asynchronous method calls inside for. Let docs = [{}, {}, {}]; for (let doc of docs) { db.post(doc).then((res)=>{}); }
6. Principle of async and await (implement async and await using generator)
Async, await The underlying layer of async, await encapsulates the invisible code implementation
You can use the iterator or generator functions to encapsulate the implementation; Reference code :(to be continued)
Data types defined before ES2019:8
6+1 raw data types + Bigint (next version)
- null
- undefined
- number
- string
- boolean
- Symbol(ES2015)
- Bigint (Stage-4, standardized in the next release)
1 reference data type Object
Special thanks: pull gou education front-end high salary training camp