var
命令会发生“变量提高”现象,既变量能够在声明以前使用,值为undefined
。我的认为,对声明的变量肯定后面不会发生更改时,即便性能上没有太大提高差别在,但使用const
,代码的可读性也会加强不少。const
实际上保证的,并非变量的值不得改动,而是变量指向的那个内存地址所保存的数据不得改动。ES6
容许按照必定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)。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)
复制代码
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]
复制代码
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
复制代码
find/findIndex
:找出第一个符合条件的数组成员以后再也不匹配,必定程度下优化查找。ios
includes
:返回 true/false
,相对于 indexOf
,使用多了es6
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) 也是展开两层...
复制代码
flatMap()
: 在数组执行 map
方法后执行 flat
, 用的很少,其实能够写 map
后写 flat
更好懂点。注意兼容性问题!![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()
复制代码
function flatten(arr) {
return arr.reduce((list, item) => list.concat(Array.isArray(item) ? flat(item) : item), [])
}
复制代码
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
!web
const name = 'guodada'
const newStr = `welcome ${name}` // welcome guodada
// the same as
const newStr = 'welcome ' + name
复制代码
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)
}
}
复制代码
ps 虽然好用,可是有时候适用场景很差,好比咱们在拉取列表和用户信息须要同时进行时,await 后才执行下一条语句,这不是咱们但愿看到的。解决方法以下:json
// 结合 Promise.all
const [result1, result2, result3] = await Promise.all([anAsyncCall(), thisIsAlsoAsync(), oneMore()])
复制代码
传送门:asyncaxios
主要是抽离代码逻辑,使得服用性增强。同时,class
的形式会让结构变得更加清晰,譬如:api
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()
,这里没用到更多知识请阅Class 的基本语法promise
- 当逻辑或 || 时,找到 true 的分项就中止处理,并返回该分项的值,不然执行完,并返回最后分项的值。
- 当逻辑与 && 时, 找到 false 的分项就中止处理, 并返回分项的值。
const a = 0 || null || 3 || 4
console.log(a) // 3
const b = 3 && 4 && null && 0
console.log(b) // null
复制代码
if/else
地狱般的调用const [age, name, sex] = [22, 'guodada', 1]
if (age > 10) {
if (name === 'guodada') {
if (sex > 0) {
console.log('all right')
}
}
}
// better 使用 &&
if (age > 10 && name === 'guodada' && sex > 0) {
console.log('all right')
}
// 或者(太长了不推荐)
age > 10 && name === 'guodada' && sex > 0 && console.log('all right')
复制代码
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
比 if/else
代码结构好点,但也和它同样有时十分冗长。markdown
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
复制代码
更多详见Set 和 Map
function func(name, age = 22) {}
// 等同于
function func(name, age) {
age = age || 12
}
复制代码
const a = 1
return a === 1 ? true : false
// 画蛇添足了,其实就等于
return a === 1
复制代码