Ваш путеводитель по лаконичному JavaScript
Код, который легче всего поддерживать, — это код, который вы никогда не пишете
Вы, наверное, знаете эту поговорку. Мне всегда нравилось, чтобы мой код был чистым и кратким, надеясь, что это поможет людям, которые будут заниматься проектом в будущем. Мне также было бы полезно поддерживать этот проект, потому что я могу забыть некоторые аспекты, а легко читаемая кодовая база дает всем хороший старт.
Посмотрим, как ты сможешь писать меньше JS код и сделать проект более легким для чтения/обслуживания/отладки.
Примечание:в этой статье представлен набор хорошо известных концепций и несколько соответствующих примеров.
Оглавление:
- Строки шаблона
- forEach, отображать и уменьшать
- Стрелочные функции
- асинхронно / жду
- Вспомогательные библиотеки: lodash, underscore
1. Строки шаблона
Это просто, и вы, вероятно, уже используете его. Вместо использования +
чтобы объединить строки и переменные, вы можете использовать синтаксис обратной галочки (`).
console.log('My name is ' + name + ' and I\'m ' + age + ' years old.')
// becomes
console.log(`My name is ${name} and I'm ${age} years old.`)
Обратите внимание, как ${}
используется для вставки переменные в шаблон строки.
Вы всегда можете выполнять основные операции или использовать условный тернарный оператор внутри фигурных скобок:
console.log(`x + y = ${x + y}`)
console.log(`You ${ age >= 18 ? 'can' : 'can\'t' } drive`)
Еще одна интересная вещь, которую вы можете сделать с помощью этого синтаксиса, — это создание многострочный струны.
const multiline = `
This is just another
multiline
string.
`
Дополнительные сведения о строках шаблона.
2. forEach, отображать и уменьшать
а. для каждого
Прошло много времени с тех пор, как я написал for
цикл в JavaScript. Давайте сравним его с forEach
.
const books = [
{name: 'How to win friends and influence people', year: 1936},
{name: 'The Four Steps to the Epiphany', year: 2005},
{name: 'Brave New World', year: 1932}
]
// traditional for loop
let step;
for (step = 0; step < books.length; step++) {
console.log(books[step].name);
}
// forEach loop
books.forEach(function(book) {
console.log(book.name);
});
forEach
будет работать с каждым массивом в JavaScript.
б. карта
map
работает с массивами (например, forEach), и это возвращает новый массив полученный в результате вызова предоставленной функции для каждого элемента исходного массива. Конечно, вы могли бы сделать это с помощью for
или же forEach
но map
обеспечивает простейший синтаксис.
let upperCaseBookTitles = [];
books.forEach(function(book) {
upperCaseBookTitles.push(book.name.toUpperCase());
});
console.log(upperCaseBookTitles)
// ['HOW TO WIN FRIENDS AND INFLUENCE PEOPLE', 'THE FOUR STEPS TO THE EPIPHANY', 'BRAVE NEW WORLD']
upperCaseBookTitles = books.map(function(book) {
return book.name.toUpperCase();
});
console.log(upperCaseBookTitles)
// ['HOW TO WIN FRIENDS AND INFLUENCE PEOPLE', 'THE FOUR STEPS TO THE EPIPHANY', 'BRAVE NEW WORLD']
в. уменьшать
reduce
действительно полезно, когда вам нужно уменьшить массив до значения/объекта. Применяется так называемый редуктор функция (предоставленная вами) для каждого значения в вашем массиве.
Допустим, мы хотим получить самую новую книгу в нашем массиве. Вот как вы это делаете с reduce
. (это глупый пример, но вы поняли)
let newestBook = books.reduce(function (acc, cur) {
if (acc.year < cur.year) acc = cur;
return acc;
}, {year: 0});
Первый параметр функции reduce
это редуктор функция. Он имеет 2 параметра:
- акк = это аккумулятор — куда мы помещаем значение, которое пытаемся получить
- cur = это Текущий элемент массива доступен на каждой итерации
Второй параметрreduce
— начальное значение аккумулятора.
Как я уже говорил ранее, мы могли бы получить тот же результат с for
или же forEach
.
3. Стрелочные функции
Сначала несколько примеров.
function() {}
// becomes
() => {}
function sum(a,b) {
return a + b;
}
// becomes
const sum = (a,b) => a + b // notice how return and the curly brackets can be dropped if the function body has only one line
function (x) {
return x;
}
// becomes
(x) => { return x; }
// or even better
x => x // the brackets are not mandatory if the function has only one argument
В двух словах, стрелочные функции были введены, чтобы предложить более короткий синтаксис и решить несколько этой проблемы (что происходит особенно при выполнении ООП)
Теперь давайте посмотрим, как мы можем использовать этот синтаксис с forEach
, map
а также reduce
функции.
для каждого
books.forEach(function(book) {
console.log(book.name);
});
// becomes
books.forEach(book => console.log(book.name));
карта
upperCaseBookTitles = books.map(function(book) {
return book.name.toUpperCase();
});
// becomes
upperCaseBookTitles = books.map(book => book.name.toUpperCase());
уменьшать
Мы можем преобразовать редуктор с помощью условный тернарный оператор и получить однострочный.
let newestBook = books.reduce(function (acc, cur) {
if (acc.year < cur.year) acc = cur;
return acc;
}, {year: 0});
// becomes
let newestBook = books.reduce((acc, cur) => acc.year < cur.year ? cur : acc, { year: 0 });
На этом этапе, я думаю, вы можете получить представление о том, как многого вы можете достичь, комбинируя forEach
, map
а также reduce
со стрелочными функциями.
Подробнее о стрелочных функциях.
4. асинхронно/ожидание
ад обратного звонка это реально. Вы, вероятно, оказывались в ситуации, когда вам приходилось передавать обратные вызовы, чтобы убедиться, что код выполняется в нужный момент. Это нормально, но если проект будет расти, вам (и другим) будет трудно читать код.
Давайте посмотрим на это в действии!
Примечание: Учтите, что getResourceA, getResourceB и getResourceC являются асинхронными функциями.
getResourceA(function(error, resourceA) {
if (!error) {
getResourceB(function(error, resourceB) {
if (!error) {
getResourceC(function(error, resourceC) {
if (!error)
console.log('Resources', resourceA, resourceB, resourceC);
else {
// do something with error
}
})
} else {
// do something with error
}
})
} else {
// do something with error
}
})
Первым решением для ада обратных вызовов был Обещать. Я много использовал обещания в своей работе, и это хорошее решение а попробовать однозначно рекомендую. Но сейчас мы сосредоточимся на async/await.
Первый шаг — определите свои асинхронные функции с использованием async
ключевое слово.
async function getResourceA() {
try {
let users = await fs.readFile('/etc/passwd', 'utf8');
// note: readFile is async and it can be called with await
// you can use await only within an async function
} catch (err) {
throw err;
}
return users;
}
async function getResourceB {...}
async function getResourceC {...}
Затем все, что вам нужно сделать, это вызвать вновь созданные асинхронные функции, используя await
.
try {
let resourceA = await getResourceA();
let resourceB = await getResourceB();
let resourceC = await getResourceC();
// use resources as you wish
} catch (err) {
console.error('Something went wrong: ', err);
}
Хорошей практикой является заключение асинхронных вызовов в блоки try-catch.
Я дам вам сравнить код и выбрать тот, который вам нравится.
Подробнее об асинхронности/ожидании.
5. Вспомогательные библиотеки: lodash, underscore, ramda
настоятельно рекомендую проверить подчеркивать или же лодаш. Если вам интересно, в чем разница между ними, проверьте это отвечать на StackOverflow.com.
Вы можете видеть lodash/underscore как набор расширенных функций, готовых помочь вам в различных сценариях, таких как: работа с массивами, объектами или строками. Взгляните на их документы, и вы найдете несколько действительно мощных функций.
Лично я начал экспериментировать с в рамке потому что я заинтересовался функциональное программирование. Я не могу рекомендовать эту серию сообщений в блоге под названием Мышление в Рамде.
Зачем использовать служебную библиотеку?
Во-первых, вы в конечном итоге будете писать меньше кода. Не менее важно, это силы вы должны соответствовать их API, и это приводит к более чистому и читаемому коду. Это также может вдохновить вас на создание собственных правил стиля кодирования.
Выводы
Меньше — больше. Но вы не должны жертвовать ясностью ради написания меньшего количества кода. Хороший разработчик не пишет код, узнаваемый только им; хороший разработчик пишет код, понятный команде или разработчику, который продолжит свою работу.
В курсе, экспериментировать с новыми вещами и сохранить те, которые работают для вас.
Дайте мне знать, чего не хватает в этом списке. Что еще техники вы используете для написания краткого JS?
Код включен!