Совместимость с IE? Его не существует?
Фактически, используя новый синтаксисbabelТранскодирование уже может решить эти проблемы. В таком случае используйте новый синтаксис, чтобы узнать, как лучше писать код.
Ниже приведены общие навыки написания JS для личного развития, я надеюсь помочь вам.
использовать пусть / константа
varКоманда будет иметь явление «продвижения переменной», то есть переменная может использоваться до объявления, а значение равноundefined. Это явление несколько странное.
Лично, когда определяется, что объявленные переменные не будут изменены в дальнейшем, даже если особой разницы в производительности нет, используяconst, читабельность кода также будет значительно улучшена.
-
constНа самом деле гарантируется не то, что значение переменной не может быть изменено, а то, что данные, хранящиеся в адресе памяти, на который указывает переменная, не могут быть изменены. -
letАдрес памяти, на который указывает переменная, сохраняет только указатель на фактические данные.
ПополнитьconstОпределенная переменная не является неизменяемой, но сохраненный адрес ссылки не может быть изменен. Примеры следующие:
const person = { age: 22 }
person.age = 1
console.log(person.age ) // 1
смотрите подробностикоманды let и const
присваивание деструктуризации
ES6Позволяет извлекать значения из массивов и объектов и присваивать значения переменным по определенному шаблону, который называется деструктурированием (Destructuring).
Преимущество в том, что он решает проблему именования доступа к многоуровневым вложенным объектам или массивам, уменьшая объем кода.
Объявите несколько переменных:
// 声明变量
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']]
Используйте сокращение вместо фильтра + карты
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()])
Портал:асинхронная функция
Инкапсулируйте код с помощью классов
Это в основном для извлечения логики кода, что повышает возможность повторного использования генерации. в то же время,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
уменьшать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
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 || 22 } - использовать
===заменять==. На самом деле это знают все. . . - Стрелочные функции, наиболее часто используемый синтаксис в es6.
- return boolean
const a = 1 return a === 1 ? true : false // 多此一举了,其实就等于 return a === 1
Пожалуйста, добавьте. Общение может прогрессировать, смотреть друг на друга и улыбаться, хе-хе.