兼容 IE ?不存在的好嗎。react
其實使用新語法配合 babel
的轉碼,已經能夠解決這一些問題了。既然如此,那就多使用新語法去探索一下怎麼更好的去寫代碼吧。ios
下面分享我的開發中經常使用的 js 寫法技巧,但願對各位有所幫助。git
var
命令會發生」變量提高「現象,即變量能夠在聲明以前使用,值爲 undefined
。這種現象多多少少是有些奇怪的。es6
我的認爲,對聲明的變量肯定後面不會發生更改時,即便性能上沒有太大提高差別在,但使用 const
, 代碼的可讀性也會加強不少。github
const
實際上保證的,並非變量的值不得改動,而是變量指向的那個內存地址所保存的數據不得改動。let
變量指向的內存地址,保存的只是一個指向實際數據的指針補充 const
定義的變量不是數據不可變,而是保存的引用地址不能發生改變。例子以下:json
const person = { age: 22 }
person.age = 1
console.log(person.age ) // 1
複製代碼
詳情看 let 和 const 命令axios
ES6
容許按照必定模式,從數組和對象中提取值,對變量進行賦值,這被稱爲解構(Destructuring
)。api
好處就是:解決了訪問多層嵌套的對象或數組的命名,減小代碼量數組
聲明多個變量:promise
// 聲明變量
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
複製代碼
使用在對象中:
const obj = {
name: {
firstName: 'guo',
lastName: 'dada'
}
}
// 提取變量
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}
複製代碼
es6 擴展符有不少用法,他可使你的代碼更加簡潔,易懂。這裏就舉例經常使用的用法
在對象中的用法:
let obj = {
name: 'guodada',
age: 22,
sex: 1
}
// 複製對象。擴展符爲淺複製!!!
const copy = { ...obj }
// 修改對象屬性值(生成新對象) 至關於 Object.assgin({}, obj, { age: 18 })
const newObj = { ...obj, age: 18 }
// 結合結構賦值
let { sex, ...z } = obj
z // { name: 'guodada', 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 等對象數組不可用
[...new Set(arr2)] // [4, 5, 6]
複製代碼
擴展符的其餘用法請自行查資料。
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
: 找出第一個符合條件的數組成員以後再也不匹配,必定程度下優化查找。 includes
: 返回 true/false
, 相較於 indexOf
, 實用多了
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), [])
}
複製代碼
補充經常使用的對象轉數組的用法:
const obj = { name: 'guodada' }
Object.keys(obj) // ['name']
Object.values(obj) // ['guodada']
Object.entries(obj) // [['name', 'guodada']]
複製代碼
使用 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.agt > 18 ? '成年' : '未成年'})
return list
}, [])
console.log(result)
複製代碼
用的挺多的,注意不兼容 IE
!
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
後才執行下一條語句,這不是咱們但願看到的。解決方法以下:
// 結合 Promise.all
const [result1, result2, result3] = await Promise.all([anAsyncCall(), thisIsAlsoAsync(), oneMore()])
複製代碼
傳送門:async 函數
主要是抽離代碼邏輯,使得代複用性增強。同時,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()
, 這裏沒用到更多知識請閱 Class 的基本語法
當邏輯或
||
時,找到爲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')
複製代碼
提一下 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
比 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
複製代碼
更多詳見 Set 和 Map 數據結構
function func(name, age = 22) {}
// 等同於
function func(name, age) {
age = age || 22
}
複製代碼
===
代替 ==
。其實你們都懂這個的。。。const a = 1
return a === 1 ? true : false
// 畫蛇添足了,其實就等於
return a === 1
複製代碼
敬請各位補充。交流才能進步,相視一笑,嘿嘿。