Part1-2 ES new features with TypeScript and JS performance optimizations

1.ECMAScript

ECMAScript (ES for short) is generally considered the standard specification for JavaScript, an extension language of ECMAScript. ECMAScript started naming ECMAScript in 2015 using a year. ECMAScript2015 became ES6, followed by ES2016, ES2017, and ES2018.

2. ES new features

2.1 Differences between let, const, and VAR

// let const forms a block-level scope with no promotion of variable declarations
// let is used to declare variables
// for (var i = 0; i < 3; i++) {
// console.log(i);
// }
// console.log(i);
for (let i = 0; i < 3; i++) {
  console.log(i);
}
// console.log(i);

// const declares a constant. It cannot be changed once declared
const b = 1;
Copy the code

2.2 Array deconstruction

// Array destruct
const arr = ['one'.'two'.'three']
const [, str1,str] = arr
console.log(str1, str); // two three
Copy the code

2.3 Object deconstruction

// Object deconstruction
const obj = {
  name: 'zs'
}
// : Set the alias to prevent name conflicts
const { name: namea } = obj
console.log(namea);
Copy the code

2.4 Template Strings

// Template string
// const str = `123`
// A tagged template string that can be used to process interpolating data within a string
const name = 'tom'
const gender = true
const tag = (s, name, gender) = > {
  console.log(s, name, gender);
  const sex = gender ? 'man' : 'women'
  return s[0] + name + s[1] + sex
}
const str1 = tag`hi, my name is ${name}, I am a ${gender}`
console.log(str1); // hi, my name is tom, I am a man
Copy the code

2.5 Arrow Function

// Arrow function
const fn = (a, b) = > a + b 
const arr = [1.2.3]
const result = arr.filter(v= > v % 2)
// Does not change the this direction
const obj = {
  name: 'zs'.sayHi: function () {
    console.log('my name is ' + this.name);
  },
  sayHi1: () = > {
    console.log('my name is ' + this.name);
  }
}
obj.sayHi() // my name is zs
// this applies to the current scope, context
obj.sayHi1() // my name is undefined
Copy the code

2.6 Object literals

// Object literals
const name = 'zd'
const age = '18'
const obj1 = {
  name,
  age,
  // fn: function () {}
  fn () {
    console.log(this); }}console.log(obj1); // { name: 'zd', age: '18', fn: [Function: fn] }
obj1.fn() // { name: 'zd', age: '18', fn: [Function: fn] }
Copy the code

2.7 the Proxy

// proxy
const obj = {
  name: 'zs'.age: 18
}
const proxyObj = new Proxy(obj, {
  get (target, property) {
    console.log(target, property);
    // return 100
    return property in target ? target[property] : 'none'
  },
  set (target, property, value) {
    if (property === 'age') {
      if (!Number.isInteger(value)) {
        throw new Error('Error')
      }
    }
    target[property] = value
  },
  deleteProperty (target, property) {
    console.log(target, property);
    delete target[property]
  }
})
// proxyObj.age = '19' // Error
proxyObj.age = 19 // { name: 'zs', age: 19 }
console.log(proxyObj.name); // zs
console.log(proxyObj.name1); // none

// Compare Proxy and defineProperty
delete proxyObj.name
console.log(proxyObj);

const p1 = {}
Object.defineProperty(p1, 'age', {
  get () {
    console.log('age accessed ');
    return p1._age
  },
  set (val) {
    console.log('Age set'); }})Object.defineProperty(p1, 'name', {
  get () {
    console.log('name accessed ');
    return p1._name
  },
  set (val) {
    console.log('Name set');
  }
})
p1.age = 1
console.log(p1.age);
Copy the code

Proxy data hijacking is more convenient than Object.defineProperty and adds many new methods that Object.defineProperty does not have.

2.8 Reflect

// Reflect 
const obj = {
  name: 'zs'.age: 18
}
const proxyObj = new Proxy(obj, {
  get (target, property) {
    console.log(target, property);
    return Reflect.get(target, property)
  }
})
console.log(proxyObj.name);
// The unified operation object API
console.log(
  Reflect.has(obj, 'name'),
  Reflect.ownKeys(obj),
  Reflect.deleteProperty(obj, 'age'),Copy the code

2.9 class class

// class
// function Person (name) {
// this.name = name
// }
// Person.prototype.say = function () {
// console.log(`${this.name}`);
// }
class Person {
  constructor (name) {
    this.name = name
  }

  say () {
    console.log(`my name is The ${this.name}`); }}const p = new Person('tom')
p.say()
Copy the code

2.9.1 static Static modifiers

// Static method modifier static
class Person {
  constructor (name) {
    this.name = name
  }

  say () {
    console.log(`my name is The ${this.name}`);
  }

  static create (val) {
    return new Person(val)
  }
}
Person.create('zs').say()
Copy the code

2.9.2 inheritance extends

/ / extends to inherit
class Teacher {
  constructor (name, age) {
    this.name = name
    this.age = age
  }
  say () {
    console.log(`my name is The ${this.name}, i am The ${this.age} years old`); }}class Student extends Teacher {
  constructor (name, age, num) {
    // Invoke the parent's properties
    super(name, age)
    this.num = num
  }

  hello () {
    // Call the parent method
    super.say()
    console.log(`my num is The ${this.num}`); }}const s = new Student('jack'.12.123)
s.hello()
// my name is jack, i am 12 years old
// my num is 123
Copy the code

2.10 Set data structure

// set data structure
const s = new Set(a)// add: Add elements to set
s.add(1).add(2).add(3)
console.log(s); // Set { 1, 2, 3 }
// for a loop
for (let i of s) {
  console.log(i);
}
// size: length
console.log(s.size);
// has: determines whether there is an element
console.log(s.has(100));
// delete: Deletes an element. Returns true on success and false on failure
console.log(s.delete(1));
// clear: clears set
s.clear()
console.log(s); // Set {}
// Array decrement
const arr = new Set([1.2.2.3.1.5.5])
console.log(arr); // Set { 1, 2, 3, 5 }
console.log([...arr]); // [1, 2, 3, 5]
console.log(Array.from(arr));// [1, 2, 3, 5]
Copy the code

2.11 Map Data structure

// Map data structure
// You can use any type of value as a key
// Normal object structure
const obj = {}
obj[123] = 123
obj[true] = 345
obj[{a: 123}] = 456
// The value toString is automatically followed as a key
console.log(obj); // { '123': 123, true: 345, '[object Object]': 456 }
console.log(obj[{}]); / / 456

// map 
const m = new Map(a)const a = { name: 'tom'}
m.set(a, 10)
m.set(true.101)
m.set(123.16)
/ / traverse
m.forEach((value, key) = > {
  console.log(value, key);
})
// 10 { name: 'tom' }
// 101 true
/ / 16, 123
console.log(m); // Map { { name: 'tom' } => 10 }
console.log(m.get(a)); / / 10
m.delete(a)
console.log(m); // Map { true => 101, 123 => 16 }
/ / to empty
m.clear()
console.log(m); // Map {}
Copy the code

2.12 Symbol Data type

Symbol data type

// Unique presence
const s1 = Symbol(a)const s2 = Symbol(a)console.log(s1 === s2); // false
// We can give the Symbol a nickname for it
console.log(
  Symbol('a'),
  Symbol('b'),
  Symbol('c'));// Symbol(a) Symbol(b) Symbol(c)
// Set a unique property for the object
const name = Symbol(a)const obj = {
  [name]: 'zs'.say() {
    console.log(`my name is The ${this[name]}`);
  }
}
obj.say()

// symbol. for, the argument is converted to a string by calling the toString method
console.log(Symbol.for('foo') = = =Symbol.for('foo')); // true
console.log(Object.getOwnPropertySymbols(obj)); // [ Symbol() ]
const obj1 = {
  [Symbol.toStringTag]: 'xObj' // [object xObj]
}
console.log(obj1.toString()); // [object Object]

Copy the code

2.13 the for… Of traversal

For of a way to traverse all data structures

// Array traversal can be stopped at any time by using break
const arr = [1.2.3.3.5]

for (const item of arr) {
  if (item > 2) {
    break
  }
  console.log(item);
}
/ / set traversal
const s = new Set([1.2.3])
for (const i of s) {
  console.log(i);
}
/ / map traverse
const m = new Map()
m.set('name'.'zs')
m.set('age'.18)
for (const [key, value] of m) {
  console.log(key, value);
}
// Common objects cannot be iterated. Obj is not iterable
// const obj = { a: 1, b: 2}
// for (const v of obj) {
// console.log(v);
// }
Copy the code

2.14 Iterable Iterable interface

// Iterable Iterable interface
// Implement the Iterable interface for... of... The premise of
// iterator
const arr = ['one'.'two']
const iterator = arr[Symbol.iterator]()
console.log(iterator.next()); // { value: 'one', done: false }
console.log(iterator.next()); // { value: 'two', done: false }
console.log(iterator.next()); // { value: undefined, done: true }

// Implement the Iterable interface
const obj = {
  store: ['one'.'two'.'three'].// Return an iterator
  [Symbol.iterator]: function () {
    const self = this
    let index = 0
    // Returns an implementation iterator object
    return {
      // Provide a next method
      next: function () {
        // Returns the iteration result
        const result = {
          value: self.store[index], // Store the result
          done: index >= self.store.length // indicates iteration status
        }
        index++
        return result
      }
    }
  }
}
for (const key of obj) {
  console.log(key);
}
Copy the code

3.TypeScript

3.1 assertions

const arr = [100.200.300]
const res = arr.find(x= > x > 0)
// Two ways to set assertions
const num  = res as number
const num1 = <number>res
// const num1 = res * res
Copy the code

3.2 the enumeration

// Starts from 0 by default
enum Status {
  Empty, 
  One,
  Two
}
// After setting the initial value, the following values are accumulated
// enum Status {
// Empty = 6,
// One,
// Two
// }
// After the string is set, all subsequent values are set to strings
// enum Status {
// Empty = 'abc',
// One = 'bcd',
// Two = 'edg'
// }

const obj = {
  value: Status.Empty / / 1. 2
}
Copy the code

3.3 Tuple type

// Specify the number of elements and an array for each element type
const tuple: [number, string] = [1.'2']
const [age, name] = tuple
Object.entries({
  name: 'zs'.age: 18
})
Copy the code

3.4 an array

// There are two common ways
const arr1: Array<number> = [1.2]
const arr2: number[] = [222.333]

function getSum (. args: number[]) {
  return args.reduce((a, c) = > a + c, 0)
}
getSum(1.2)
Copy the code

3.5 object

const foo: object = [] // {} function
const obj1: { foo: number } = { foo: 1 }
Copy the code

3.6 interface interface

/ / interface
interface Post {
  name: string
  age: number title? : string// Optionalreadonly nickname? : string// Read-only attribute
}
function say (obj: Post) {
  console.log(obj.name);
  console.log(obj.age);
}
say({
  name: 'sz'.age: 18
})

interface cash {
  // Key can be any string used to constrain the key and declare its type
  [key: string]: string
}
const cash: cash = {}
cash.a = '12'
cash.b = '12'

Copy the code

3.7 class class

class Person {
  public name: string // Public attributes
  private age: number // Private attributes
  protected readonly gender: boolean / / read-only

  constructor (name: string, age: number) {
    this.name = name
    this.age = age
    this.gender = true
  }

  sayHi (msg: string) {
    console.log(`I am a The ${this.name}.${msg}`); }}class Student extends Person {
  constructor (name: string, age: number) {
    super(name, age)
  }
}

const p1 = new Person('zs'.18)
console.log(p1.name);
// console.log(p1.age); / / an error
// console.log(p1.gender); / / an error

/ / class
interface Eat {
  eat (food: string): void
}
interface Run {
  run (food: string): void
}


class Person implements Eat.Run {
  eat (food: string): void {
    console.log(food);
  }
  run (distance: string): void {
    console.log(distance); }}class Dog implements Eat.Run {
  eat (food: string): void {
    console.log(food);
  }
  run (distance: string): void {
    console.log(distance); }}/ / abstract classes
abstract class Animal {
  eat (food: string): void {
    console.log(food);
  }
  abstract run (distance: string): void
}

class Dog1 extends Animal {
  run(distance: string): void {
    console.log(distance); }}Copy the code

3.8 paradigm

// declare function 
      
       , undefined type: T
      
function ceateArr<T> (length: number, value: T) :T[] {
  const res = Array<T>(length).fill(value)
  return res
}

ceateArr(3.100)
ceateArr(3.'100')

const cetAA = <T>(length: number, value: T): T[] => {
  const res = Array<T>(length).fill(value)
  return res
}
cetAA(12.12)
cetAA(12.'12')
Copy the code

4. Js performance optimization

GC collection algorithm commonly used in V8 engines

// Performance optimization
// Gc collection mechanism
/** * 1. Reference count method * Core idea: set the number of references, determine whether the current reference count is 0 * reference counter, reference relationship changes to modify the reference value, reference count is 0, recycling * Advantages: garbage immediately recycling, minimize program pause * disadvantages: Unable to recycle objects referenced in a loop, time consuming */

/** * 2. Mark clearing algorithm * Core idea: divide mark and clear two stages to complete * traversal all objects to find mark active objects * traversal all objects to clear no mark objects * reclaim the corresponding space * Advantages: Solves the problem of unable to recycle reference objects * disadvantages: Resulting in space fragmentation, not immediately recovered */

/** * 2. Mark collation algorithm * Core idea: divide mark and clear two stages * traverse all objects to find mark active objects * traverse all objects to clear no marked objects * Collate before recycling, adjust position * reclaim corresponding space * Advantages: Fixed the problem of not being able to recycle objects referenced by loop * Disadvantages: reduced space fragmentation */
 
/** * V8 garbage collection strategy: * 1. Memory is divided into new generation and old generation * 3. Different algorithms are used for different objects */

/** * Common reclamation algorithm: * 1. Generational reclamation * 2. Spatial replication * 3. Tag cleanup * 4. Tag cleanup * 5. Tag increment */

/** * V8 memory allocation: * 1. Small space is used to store new generation objects, that is, objects that have a short lifetime (32 m for 64-bit systems and 16M for 32-bit systems). Copy algorithm + mark collation * 2. New generation memory is divided into two Spaces of equal size * 3. Use space From, used To store live objects, free space To * 4. After mark collation, copy live objects To free space To * 5. It is possible To get promoted during copying (moving new generation objects To old generation) * 2. New generation objects survive after a round * 3. To reach 25% space usage, triggering promotion */

/** * Old generation collection: * 64 bit system 1.4GB, 32 bit system 700M * old generation object is the object with a long life ** recycle mechanism: * 1. Tag cleanup, tag cleanup, incremental tag, these algorithms implement * 2. First try tag cleanup, garbage collection free space * 3. 4. Use incremental markup for efficiency optimization * */
Copy the code