Я переписал эти 10+ отдельных строк кода JavaScript, руководитель группы похвалил код за его элегантность
Этот пост является ответом, но ни в коем случае не раскопками на пост в блоге, написанный Zard-x на Medium под названием «Я написал эти 10+ одиночных строк кода JavaScript; Руководитель группы похвалил код за его элегантность».
Однострочники - это действительно классные задачи, и их очень весело создавать. Раньше я тратил много своего времени на codewars.com и codingame.com, которые представляют собой два веб-сайта, облегчающих небольшие задачи по кодированию, которые бросают вызов вашей способности писать короткий код или писать код быстро.
В то время как код-гольф может служить забавным инженерным упражнением, их уроки редко следует использовать в реальном мире, а когда они используются, менеджеры по разработке ни в коем случае не должны поощрять разработчиков использовать этот тип кода в кодовой базе. Когда вы находитесь в среде совместной работы, написание хорошего кода должно быть приоритетом. Это означает, что код удобочитаем, ремонтопригоден и надежно работает.
Код-гольф — это вид развлекательного соревнования по компьютерному программированию, в котором участники стремятся получить как можно более короткий исходный код, решающий определенную задачу
— Википедия, Кодекс гольфа
Дедупликация массива
Оригинальный исходный код
const uniqueArr = (arr) => [...new Set(arr)];
Я не обязательно против распространенного приема удаления дубликатов из массивов путем создания экземпляра и распространения набора, но из-за количества раз, когда вы индексируете массив, это может быть довольно плохо с точки зрения производительности.
Переписанный исходный код
const removeDuplicates = (array) => {
const uniqueValues = [];
const seenMap = {};
for (const item of array) {
if (seenMap[item]) continue;
seenMap[item] = true;
uniqueValues.push(item);
}
return uniqueValues;
};
На массиве из 1000 000 случайно сгенерированных чисел в диапазоне от 1 до 100 исходный код работает только на 12% быстрее, чем переписанная версия. Поскольку мы используем map во второй функции, нам нужно выполнить итерацию по массиву только один раз, и мы сделали это так, что проверка того, видели ли мы уже элемент, занимает O(1) времени.
Код устраняет «уловки» и вместо этого использует хорошо известную концепцию, такую как хэш-карты, которые могут уменьшить количество запросов других разработчиков к вашему коду. В коде также есть переменные с правильными именами, причем имя функции removeDuplicates
определяет действие, которое выполняет функция, а не двусмысленное имя, такое как uniqueArr
. Кроме того, в нем не используются чрезмерно сокращенные слова, что упрощает код для тех, для кого английский язык не является родным. чтобы понять.
Обратите внимание, что функция не документирована. Чрезмерная документация иногда может быть плохой вещью. Если ваши имена переменных правильно названы, ваши комментарии могут оказаться излишними, и это хорошо! Если это произойдет, с радостью бросьте их и отправьте!
const removeDuplicates = (array) => {
// Turn our array into a Set, which can only contain
// unique values, and then make an array from that set.
return [...new Set(array)];
};
Получить параметры из URL-адреса и преобразовать их в объект
Оригинальный исходный код
const getParameters = URL => JSON.parse(`{"${decodeURI(URL.split("?")[1]).replace(/"/g, '\\"').replace(/&/g, '","').replace(/=/g, '":"')}"}`
Если бы в этом коде была ошибка, насколько бы вы обрадовались, узнав, что это та функция, над которой вы будете работать? Скорее всего, не так уж и много. Не говоря уже о том, что пересборки объектов JSON со строками — это то, чего следует избегать, насколько это возможно, в данном случае это было бы довольно просто.
Переписанный исходный код
/**
* Returns the provided URLs search parameters
* as a set of key-value pairs.
*/
const getURLParameters = (url) => {
const { searchParams } = new URL(url);
return Object.fromEntries(searchParams);
};
В переписанном коде для этой функции мы используем удобный нативный JavaScript API URL, который автоматически вызывает для нас экземпляр объекта URLSearchParams, а затем мы просто используем функцию Object#fromEntries
для результирующего объекта! Это избавляет нас от необходимости вручную создавать объект JSON, смешивая и искажая строки.
Обратите внимание, что мы предоставили комментарий для этой функции! Несмотря на то, что я включил в имя функции getURLParameters
спецификацию, какой тип параметров обрабатывает функция, не обязательно ясно, в каком формате будет результирующий объект.
Проверьте, является ли объект пустым
Оригинальный исходный код
const isEmpty = obj => Reflect.ownKeys(obj).length === 0 && obj.constructor === Object;
Использование ownKeys или Object.keys не очень эффективно при проверке, является ли объект пустым.
Переписанный исходный код
const isObjectEmpty = (object) => {
// Iterates over the keys of an object, if
// any exist, return false.
for (_ in object) return false;
return true;
};
Этот переписанный код — метод старой школы, и он прошел проверку временем! Переписанный исходный код работает в 20 раз быстрее, чем исходный метод, и это только с двумя свойствами объекта. Повышение производительности связано с тем, что вам больше не нужно создавать массивы, копировать значения и индексировать ключи. Вы видите одну клавишу, и вы избежали функции!
Может быть не сразу понятно, почему мы перебираем ключи объекта, поэтому мы оставили там короткий комментарий, чтобы другие разработчики знали, что происходит.
Перевернуть строку
Оригинальный исходный код
const reverse = str => str.split('').reverse().join('');
В этом случае мы не плохо начали! Мы могли бы использовать цикл for
для повышения производительности на 80% для коротких строк, и мы могли бы рассмотреть возможность реализации этого метода, если мы часто обращаем некоторые короткие строки, но в случае нечетного обращения на легковесных строках мы могли бы просто быть лучше с этой функциональностью.
Переписанный исходный код
const reverseString = (string) => {
return string
.split("")
.reverse()
.join("");
};
Разделение связанных методов на несколько строк является моим личным предпочтением, так как это позволяет мне сканировать пути функций, а не прыгать по ним, однако, если бы кто-то попросил меня изменить это, я бы не стал суетиться.
Для удовольствия, вот более производительная версия.
const reverseString = (string) => {
let reversedString = "";
for (let i = string.length - 1; i >= 0; i--)
reversedString += string[i];
return reversedString;
};
Создать случайный шестнадцатеричный код
Оригинальный исходный код
const randomHexColor = () => `#${Math.floor(Math.random() * 0xffffff).toString(16).padEnd(6, "0")}`
Еще раз, не с плохого начала! Мне особенно нравится, что мы напрямую ссылаемся на максимальное шестнадцатеричное значение, поддерживаемое для non-alpha colours. Небольшая уборка, и мы будем в деле!
Переписанный исходный код
const getRandomHexColor = () => {
const randomValue = Math.floor(Math.random() * 0xffffff);
const hexValue = randomValue.toString(16);
return hexValue.padStart(6, "0");
};
Единственное серьезное изменение, которое я сделал в этом примере, это то, что я заменил padEnd
на padStart
. Работа этой функции заключается в генерации случайного 24-битного целого числа и последующем представлении его в шестнадцатеричном формате.
Минимальное значение, которое мы можем получить, равно 0 0x000000
, а максимальное значение равно 16 777 215 0xFFFFFF
.
Допустим, наше randomValue
в конечном итоге равно 255. Тогда наше hexValue
будет равно ff
, и если мы дополним конец, наше возвращаемое значение будет #ff0000
, а если мы дополним начало, оно будет #0000ff
. Если мы затем переведем оба этих значения обратно в целые числа, #ff0000
на самом деле будет представлять значение 16 711 680, а #0000ff
будет представлять 255. Это означает, что если мы заполним конец, а не начало, мы фактически получим неправильное значение.
Вывод
Это заняло больше времени, чем ожидалось. Надеемся, что данная информация оказалась для вас информативной и полезной. До новых встреч!!!