Compatible with IE? It doesn’t exist.

Using the new syntax in conjunction with Babel transcoding already solves some of these problems. In this case, use the new syntax to explore how to write code better.

Below share personal development commonly used JS writing skills, I hope to help you.

Use let/const

The var command will cause “variable promotion”, that is, the variable can be used before the declaration, the value of undefined. This phenomenon is more or less strange.

In my opinion, using const makes code much more readable, even if there isn’t much of a performance difference, when a declared variable is guaranteed not to change later.

  • constIn fact, it is not the value of the variable that is guaranteed to remain unchanged, but the data stored in the memory address to which the variable points.
  • letThe memory address to which a variable points holds only a pointer to the actual data

A variable that complements a const definition is not immutable data, but the address of the stored reference cannot be changed. Examples are as follows:

const person = { age: 22 }
person.age = 1

console.log(person.age ) / / 1
Copy the code

See the let and const commands for details

Deconstruction assignment

ES6 allows you to extract values from arrays and objects and assign values to variables in a pattern called Destructuring.

The advantage is that it solves the problem of accessing multiple nested object or array names, reducing the amount of code

Declare multiple variables:

// Declare variables
let age = 22
let name = 'guodada'
let sex = 1

// better
let [age, name, sex] = [22.'guodada'.1]
console.log(age, name, sex) // 22, guodada, 1
Copy the code

Used in objects:

const obj = {
  name: {
    firstName: 'guo'.lastName: 'dada'}}// Extract variables
const firstName = obj.name.firstName
const lastName = obj.name.lastName

// better
const { firstName, lastName } = obj.name 
Copy the code

Used in functions:

// Get the parameters in the parameter structure assignment, when the parameter is used
function Destructuring({ name, age }) {
  return { name, age } {name: name, age: age}
}

const params = { name: 'guodada'.age: 22 }
Destructuring(params)
Copy the code

See destructively assigning variables for more uses

ES6 allows variables to be written directly to objects. In this case, the property name is the variable name, and the property value is the value of the variable.

function f(x, y) {
  return {x: x, y: y};
}

// better
function f(x, y) {
  return {x, y};
}
f(1.2) // Object {x: 1, y: 2}
Copy the code

The use of extension characters

The ES6 extender can be used in many ways to make your code simpler and easier to understand. Here are some examples of common usage

Usage in objects:

let obj = {
  name: 'guodada'.age: 22.sex: 1
}

// Copy objects. Extension for shallow copy!!
constcopy = { ... obj }Object. Assgin ({}, obj, {age: 18})
constnewObj = { ... obj,age: 18 }

// Combine structure assignment
let{ sex, ... z } = obj z// { name: 'guodada', age: 22 }
Copy the code

Usage in arrays:

const arr = [1.2.3]
const arr2 = [4.5.6.4]

// Copy the array. Extension for shallow copy!!
const newArr = [...arr] / /... [1, 2, 3] => equivalent to expanding array: 1, 2, 3

// Merge arrays
const conbineArr = [...arr, ...arr2]

// combine the maximum function
Math.max(... arr)// Implement array de-duplication with Set. Note: Arrays of objects such as JSON are not available
[...new Set(arr2)] / / [4, 5, 6]
Copy the code

Find other uses of the extender.

An array of usage

const arr = [1.2.3.4]

Array.isArray(arr) // Check whether it is an array

arr.includes(2) // true determines whether the array contains an item

arr.findIndex(d= > d === 3) // 2 Find the first member of the array that meets the criteria and return the array subscript

arr.find(d= > d === 3) // 3 Find the first member of the array and return it. If not, return undefined

// Es5 filter Map forEach, etc.
arr.every(d= > d > 2) // false Returns true if each item satisfies the condition

arr.some(d= > d > 2) // true Returns true if one of the conditions is met
Copy the code

Find /findIndex: Finds the first member of the array that matches the criteria and then does not match. Includes: Returns true/false, much more useful than indexOf

  • Flat () : Flat array, often used to convert an array to a one-dimensional array

    const arr = [1.2[3.4]]
    
    arr.flat() // [1, 2, 3, 4] flat array, default expansion one layer.
    
    const arr2 = [1.2[3.4[5.6]]]
    
    arr2.flat() // [1, 2, 3, 4, [5, 6]]
    arr2.flat(2) // [1, 2, 3, 4, 5, 6] flat(3)
    Copy the code
  • FlatMap (): Flat is executed after the array map method. It is not used much. Note compatibility issues!!

    [2.3.4].flatMap(x= > [x, x * 2]) // [2, 4, 3, 6, 4, 8]
    // 1. [2, 3, 4].map(d => [d, d * 2]) => [[2, 4], [3, 6], [4, 8]]
    // 2. [[2, 4], [3, 6], [4, 8]].flat()
    Copy the code

Additional implementation methods for flattening:

function flatten(arr) {
 return arr.reduce((list, item) = > list.concat(Array.isArray(item) ? flat(item) : item), [])
}
Copy the code

Add the usual use of object to array:

const obj = { name: 'guodada' }
  
Object.keys(obj) // ['name']
Object.values(obj) // ['guodada']
Object.entries(obj) // [['name', 'guodada']]
Copy the code

Use Reduce instead of Filter + Map

const arr = [{ sex: 1.age : 10}, { sex: 1.age : 19}, { sex: 0.age : 12}]

const result = arr.reduce((list, item) = > {
  item.sex === 1 && list.push({ sex: 'male'.age : item.agt > 18 ? 'adult' : 'minor'})
  return list 
}, [])

console.log(result)
Copy the code

Template string

Use a lot of attention is not compatible with IE!

const name = 'guodada'

const newStr = `welcome ${name}` // welcome guodada

// the same as
const newStr = 'welcome ' + name
Copy the code

Use async/await

Async /await is a syntactic candy for generator, which is used to solve asynchronous problems. There are many articles on the Internet about async/await.

async function test() {
  const data = await axios.get('https://randomuser.me/api/')
  console.log(data)
}
/ / is equivalent to
function test() {
  axios.get('https://randomuser.me/api/').then(res= > console.log(res)) // Axios is also a promise object
}

/ / try/catch
async function test() {
  try {
    const data = await axios.get('https://randomuser.me/api/')
    console.log(data)
  } catch (err) {
    console.log(err)
  }
}
Copy the code

Ps is useful, but sometimes it is not suitable for situations, such as executing the next statement after await while pulling the list and user information need to be processed simultaneously. This is not what we want to see. Solutions are as follows:

/ / Promise. All
const [result1, result2, result3] = await Promise.all([anAsyncCall(), thisIsAlsoAsync(), oneMore()])
Copy the code

Portal: async function

Encapsulate code with class

It is mainly to extract the code logic, which makes the reusability strengthened. At the same time, the class form makes the structure clearer, for example:

class MyForm {
  /** * @func defaultLimit - Default form input restriction, return true if value is null * @param {Number} type - node representing form type! * @param {String} value - Value to be validated * @return Boolean * * Validate the output based on the type attribute * 10 ≤x≤50 integer * 2-1000 ≤x≤2000 integer * 3 1≤x integer * 4 0 x or less 10 or less * /
  static defaultLimit(type, value) {
    const typeLimitMap = {
      1: /^(\d|[1-4]\d|50)$/g.2: / ^ -? (\ d {1, 3} | 1000) $| ^ (1 - | \ d {3} | 2000) $/.3: /^[1-9]\d*$/.4: value= > value <= 10 && value >= 0 // 0≤ x ≤ 10 can be a decimal
    }
    if(! typeLimitMap[type] || ! value)return true
    if (typeof typeLimitMap[type] === 'function') return typeLimitMap[type](value)
    else return typeLimitMap[type].test(value)
  }

  /** * @func translateLimit - Conversion operator * @param {String} operator - operator * @param {*} value - Matched value * @param {*} compareValue - match @ return Boolean values * * 'eq' : '=' * 'ne' : 'indicates a' * 'gt' : '>' * 'lt' : '<' * 'ge' : 'or' * 'le' : ' 'or less * /
  static translateLimit(operator, value, compareValue) {
    const type = {
      eq: value === compareValue,
      ne: value ! == compareValue,gt: value > compareValue,
      lt: value < compareValue,
      ge: value >= compareValue,
      le: value <= compareValue
    }
    if (!Object.keys(type).includes(operator) || ! value || value ===The '-') return true
    return type[operator]
  }

  // ...
}

export default MyForm
Copy the code

Use:

import MyForm from './MyForm'

MyForm.defaultLimit(1.20)
Copy the code
  • static: static property that the class can call directly
  • constructor: called when the class is instantiated, that isnew MyForm()I didn’t use it here

Read the basic syntax of Class for more information

Optimize if/else statements

When the logic or | |, find to true item stops processing, and returns the value of the item, otherwise performed, and returns the value of the last item.

When the && logic finds a false item, processing is stopped and the value of that item is returned.

const a = 0 || null || 3 || 4
console.log(a) / / 3

const b = 3 && 4 && null && 0
console.log(b) // null
Copy the code

Reduce if/else hellish calls

const [age, name, sex] = [22.'guodada'.1]

if (age > 10) {
  if (name === 'guodada') {
    if (sex > 0) {
      console.log('all right')}}}// better use &&
if (age > 10 && name === 'guodada' && sex > 0) {
  console.log('all right')}// Or (too long is not recommended)
age > 10 && name === 'guodada' && sex > 0 && console.log('all right')
Copy the code

Mention the react pit, in Render

render(){
  const arr = []
  return arr.length && null
}
// Render 0!
// Boolean/undefind/null/NaN etc will not render. We can use it!! Forcing casts to Boolean solves this problem
return!!!!! arr.length &&null

// Use && to control the rendering of components
this.state.visible && <Modal />
Copy the code

Use array. includes to handle multiple conditions:

const ages = [18.20.12]

if (age === 18 || age === 12) {
  console.log('match')}// better
if ([18.12].includes(age)) {
  console.log('match')}Copy the code

Ternary operators can be used for less judgment logic:

const age = 22
const isAdult = age >= 18 ? true : false // Const isAdult = age > 18

const type = age >= 18 ? 'adult' : 'child'
Copy the code

Optimize switch/case statements

Switch /case is better structured than if/else code, but just like it can be quite verbose.

Here’s an example from our own actual project: Sometimes we might need to perform different re validation for different types of fields to prevent users from typing incorrectly. Such as

const [type, value] = [1.'20']
/** * Verify the output based on the type attribute * 10 ≤x≤50 integer * 2-1000 ≤x≤2000 integer * 3 1≤x integer */

function func1(type, value) {
  if (type === 1) {
    return /^(\d|[1-4]\d|50)$/.test(value)
  } else if (type === 2) {
    return / ^ -? (\ d {1, 3} | 1000) $| ^ (1 - | \ d {3} | 2000) $/.test(value)
  } else if (type === 3) {
    return /^[1-9]\d*$/.test(value)
  } else {
    return true
  }
}

func1(type, value)

/ / use the switch/case
function fun2(type, value) {
  switch (type) {
    case 1:
      return /^(\d|[1-4]\d|50)$/.test(value)
    case 2:
      return / ^ -? (\ d {1, 3} | 1000) $| ^ (1 - | \ d {3} | 2000) $/.test(value)
    case 3:
      return /^[1-9]\d*$/.test(value)
    default:
      return true
  }
}

func2(type, value)
Copy the code

How can we solve this problem subtly, as follows:

function func3(type, value) {
  const limitMap = {
    1: /^(\d|[1-4]\d|50)$/g.2: / ^ -? (\ d {1, 3} | 1000) $| ^ (1 - | \ d {3} | 2000) $/.3: /^[1-9]\d*$/
  }
  return limitMap[type].test(value)
}
Copy the code

Using objects to match property values reduces your code and makes your code look cleaner. You can also use Map objects to match.

function func4(type, value) {
  const mapArr = [
    [1, /^(\d|[14 -]\d|50)$/g],
    [2, / ^ -? (\d{1.3} |1000) $| ^ (- |1\d{3} |2000) $/], [3, / ^ [19 -]\d*$/]
  ]
  const limitMap = new Map(mapArr)
  return limitMap.get(type).test(value)
}
Copy the code

A Map is a key-value pair of data structure objects that match more rigorously. It will tell if you are passing a string or a number, for example:

limitMap.get(1) // /^(\d|[1-4]\d|50)$/g
limitMap.get('1') // undefined
Copy the code

See Set and Map data structures for more

other

  • Function parameter default value
    function func(name, age = 22) {}
    / / is equivalent to
    function func(name, age) {
      age = age || 22
    }
    Copy the code
  • use= = =Instead of= =. Actually, everyone knows that…
  • Arrow functions, the most common syntax in ES6.
  • return boolean
    const a = 1
    return a === 1 ? true : false
    // It's a waste of time
    return a === 1
    Copy the code

Please add. Communication can progress, look at each other with a smile, heh heh.

  • Github – star Life is better
  • Blog – Welcome to exchange