ES6常用方法总结

ES6常用方法总结:

使用let/const
var 命令会发生“变量提升”现象,既变量可以在声明之前使用,值为undefined。个人认为,对声明的变量确定后面不会发生更改时,即使性能上没有太大提升差异在,但使用const,代码的可读性也会增强很多。

const 实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址所保存的数据不得改动。

let 变量指向的内存地址,保存的只是一个指向实际数据的指针。

解构赋值
ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构
好处就是解决了访问多层嵌套的对象或数组的命名,减少代码量
补充 const 定义的变量不是数据不可变,而是保存的引用地址不能发生改变 例子如下

const person = { age: 22 }
person.age = 1
console.log(person.age) // 1

声明多个变量

// 声明变量
let age = 22;
let name = 'guodada';
let sex = 1;

// 更好的方法 (better)
let [age, name, sex] = [22,'hehe',true]
console.log(age,name,sex) // 22, hehe, true

使用在对象中

const obj = {
    name: {
      firstName: '小明',
      lastName: '小红'
    }
  }

  // 提取变量
  const firstName = obj.name.firstName;
  const lastName = obj.name.lastName;

  // 更好的方法 (better)
  const {
    firstName,
    lastName
  } = obj.name;

使用在函数中

 // 在参数中结构赋值,获取参数,当参数多的使用时候十分方便
  function Destructuring({ name, age}){
    return {name, age} // 相当于 {name:name, age:age} 可以简写
  }

  const params = { name: 'guodada', age:22 }
  Destructuring(params)

es6 允许在对象中 直接写变量 这时属性名为变量名 属性值为变量值

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}

扩展运算符的运用
在对象中的用法

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

  // 复制对象。扩展符为浅复制!!!
  const copy = { ...obj }

  // 修改对象属性值(生成新对象) 相当于 Object.assgin({}, obj, { age: 18 })
  const newObj = { ...obj, age: 18 }

  // 结合结构赋值
  let { sex, ...hehe } = obj
  console.log(hehe) // hehe { name: 'guodata', age: 22}

在数组中的用法

  const arr = [1, 2, 3];
  const arr2 = [4, 5, 6, 4];

  // 复制数组。扩展符为浅复制!!!
  const newArr = [...arr]; // ...[1,2,3] => 相当于展开数组:1,2,3

  // 合并数组
  const conbineArr = [...arr, ...arr2];

  // 结合求最大值函数
  Math.max(...arr)

  // 结合 Set 实现数组去重。注意:json 等对象数组不可用;
  let arr3 = [...new Set(arr2)] // [4,5,6]

数组用法
使用 reduce 代替 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: '男',
      age: item.age > 18 ? '成年' : '未成年'
    })
    return list
  },[])
  console.log(result)

基本用法

const arr = [1,2,3,4];

  Array.isArray(arr) // 判断是否为数组

  arr.includes(2) // true 判断数组中是否包含某项

  arr.findIndex(d => d === 3) // 2 找出第一个符合条件的数组成员并返回数组下标, 找不到返回 -1

  arr.find(d => d === 3) // 3 找出第一个符合条件的数组成员并返回,找不到返回 undefined

  // es5 其他还有filter map forEach 等 
  arr.every(d => d > 2) // false 每一项都满足条件则返回true

  arr.some(d => d > 2) // true 只要有一项满足条件则返回true

常用的对象转数组方法

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

flat() 扁平化数组 常用于数组转化一维数组

const arr = [1, 2, [3, 4]]

arr.flat() // [1, 2, 3, 4] 扁平化数组, 默认展开一层。

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) 也是展开两层...

js数组深度去重

 var arr = [
  {id: 1, name: '周瑜1'},
  {id: 3, name: '王昭君1'},
  {id: 2, name: '李白1'},
  {id: 1, name: '周瑜2'},
  {id: 2, name: '李白1'},
  {id: 3, name: '王昭君2'}
];

let newobj = {}; 
arr = arr.reduce((preVal, curVal) => {
	newobj[curVal.name] ? '' : newobj[curVal.name] = preVal.push(curVal); 
	return preVal 
}, [])
console.log(arr)

简单数组去重

let arr = [1, 2, 3, 4, 5, 2, 4, 3,0,0]

  function Uniq(arr = []) {
    return arr.reduce((t, v) => t.includes(v) ? t : [...t, v], []);
  }
  console.log(Uniq(arr)) // 1,2,3,4,5,0

模板字符串 不兼容ie

const name = 'guodada'

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

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

使用async/await
async/await 实际上就是 generator 的语法糖, 主要用来解决异步问题,具体网上很多文章都有介绍,这里就不做多的解释吧

async function test() {
  const data = await axios.get('https://randomuser.me/api/')
  console.log(data)
}
// 等同于
function test() {
  axios.get('https://randomuser.me/api/').then(res => console.log(res)) // axios 也是 promise 对象
}

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

利用class封装代码
主要是抽离代码逻辑,使得服用性加强。同时,class的形式会让结构变得更加清晰,譬如

class MyForm {
  /**
   * @func defaultLimit - 默认表单输入限制条件, value 为空时返回 true
   * @param {Number} type - 代表表单类型的节点!
   * @param {String} value - 需要被验证的值
   * @return Boolean
   * 
   * 根据 type 属性对输出进行验证
   * 1 0≤x≤50 整数
   * 2 -1000≤x≤2000 整数
   * 3 1≤x 整数
   * 4 0≤x≤10
   */
  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 可以为小数
    }
    if (!typeLimitMap[type] || !value) return true
    if (typeof typeLimitMap[type] === 'function') return typeLimitMap[type](value)
    else return typeLimitMap[type].test(value)
  }

  /**
   * @func translateLimit - 转换操作符
   * @param {String} operator - 运算符
   * @param {*} value - 被匹配的值
   * @param {*} compareValue - 匹配的值
   * @return Boolean
   * 'eq': '='
   * 'ne': '≠'
   * 'gt': '>'
   * 'lt': '<'
   * 'ge': '≥'
   * 'le': '≤'
   */
  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 === '-') return true
    return type[operator]
  }

  // ...
}

export default MyForm

使用

import MyForm from './MyForm'

MyForm.defaultLimit(1, 20)

static :静态属性,类可以直接调用;

constructor:实例化类的时候调用,既 new MyForm(),这里没用到

优化if/else 语句
当逻辑或 || 时,找到 true 的分项就停止处理,并返回该分项的值,否则执行完,并返回最后分项的值。

当逻辑与 && 时, 找到 false 的分项就停止处理, 并返回分项的值

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

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

提一下 React 的坑点,在 render 中

render(){
  const arr = []
  return arr.length && null
}
// 渲染出 0 !
// Boolean / undefind / null / NaN 等才不会渲染。我们可以使用 !! 强制转化为 boolean 解决这个问题
return !!arr.length && null

// 使用 && 控制组件的渲染
this.state.visible && <Modal />

使用 Array.includes 来处理多重条件

const ages = [18, 20, 12]

if (age === 18 || age === 12) {
  console.log('match')
}

// better
if ([18, 12].includes(age)) {
  console.log('match')
}

如果是较少的判断逻辑则可以使用三元运算符

const age = 22
const isAdult = age >= 18 ? true : false // 这里可以写为 const isAdult = age > 18

const type = age >= 18 ? 'adult' : 'child'

优化 switch/case 语句

switch/case 比 if/else 代码结构好点,但也和它一样有时十分冗长。

这里以自己实际项目中代码举例:有时我们可能需要对不同类型的字段进行不一样的正则验证,防止用户错误地输入。譬如

const [type, value] = [1, '20']
/**
 * 根据 type 属性对输出进行验证
 * 1 0≤x≤50 整数
 * 2 -1000≤x≤2000 整数
 * 3 1≤x 整数
 */

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)

// 使用 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)

我们如何巧妙的解决这个代码冗长的问题呢,如下

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)
}

利用对象去匹配属性值,可以减少你的代码量,也使你的代码看起来更加简洁。你也可以用Map对象去匹配

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

Map 是一种键值对的数据结构对象,他的匹配更加严格。它会区分开你传递的是字符串还是数字,譬如

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

其他

函数参数默认值

function func(name, age = 22) {}
// 等同于
function func(name, age) {
  age = age || 12
}

使用 === 代替 ==。其实大家都懂这个的。。。

箭头函数,es6 最常用的语法。

return boolean

const a = 1
return a === 1 ? true : false
// 多此一举了,其实就等于
return a === 1

此文转载自前端学习栈

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值