Ваш путеводитель по лаконичному JavaScript

Код, который легче всего поддерживать, — это код, который вы никогда не пишете

Вы, наверное, знаете эту поговорку. Мне всегда нравилось, чтобы мой код был чистым и кратким, надеясь, что это поможет людям, которые будут заниматься проектом в будущем. Мне также было бы полезно поддерживать этот проект, потому что я могу забыть некоторые аспекты, а легко читаемая кодовая база дает всем хороший старт.
Посмотрим, как ты сможешь писать меньше JS код и сделать проект более легким для чтения/обслуживания/отладки.

Примечание:в этой статье представлен набор хорошо известных концепций и несколько соответствующих примеров.

Оглавление:

  1. Строки шаблона
  2. forEach, отображать и уменьшать
  3. Стрелочные функции
  4. асинхронно / жду
  5. Вспомогательные библиотеки: 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.

Подробнее о forEach.

б. карта

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?

Код включен!

Похожие записи

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *