Как писать более элегантный код — статьи по JavaScript

JavaScript
Как писать более элегантный код — статьи по JavaScript

Некоторые люди говорят, что хороший код подобен стихотворению, элегантному и осмысленному.

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

именование переменных

Для написания хорошего кода очень важно именовать переменные. Мы стараемся использовать выразительные слова.Если английский не очень хорош, мы часто используем программное обеспечение для перевода, чтобы убедиться, что нет неправильных слов. Редактор может установить соответствующие плагины для проверки орфографии и перевода.

  1. Не сокращайте/сокращайте слова, если не признано, что они могут быть сокращены/сокращены как таковые. Это приводит к плохой читаемости и неясному смыслу. Пример счетчика:Association ass,StringBuilder sb
  2. Общие переменные именуются с использованием существительных и именных словосочетаний. Напримерvalue,options,fileText,columnNameЖдать
  3. логическое имя, если оно означает "это" использоватьis..., что означает "есть"has..., указывая на "можно" использоватьcan..., что означает "возможно ли это?"...able
  4. Именование функций осуществляется в порядке глагол/объект. НапримерgetUserInfo,insertRows,clearValueЖдать
  5. избегать использования_начало,temp,myНазовите временные переменные как временные переменные, временные переменные также имеют смысл, это увеличит шум при чтении кода.
  6. Избегайте бессмысленных имен и делайте каждое имя, которое вы называете, осмысленным. НапримерuserInfo,clickCountКонтрпримерinfo,count

структура кода

Хорошая структура кода помогает нам поддерживать рациональное мышление и снизить умственную нагрузку.

использоватьconstопределение

Если нет сложной логики, используйтеconstЭтого достаточно, поэтому вам не нужно беспокоиться о переназначении переменных и возникновении непредвиденных ситуаций. Когда вы будете много писать в этом режиме, вы обнаружите, что вряд ли сможете найти несколько приложений в проекте.letМесто.

// Bad
let result = false;
if (userInfo.age > 30) {
  result = true;
}

// Good
const result = userInfo.age > 30;

логическая категоризация

В сложной логике попытайтесь объединить связанную логику и вставить пустые строки, чтобы разделить их. Сделайте структуру кода чистой и понятной.

вернуться пораньше

существуетfunctionЧасто встречается, что значение переменнойundefinedВ этом случае нужно заранее судить и предотвращать выполнение, чтобы избежать каких-то ненужных ветвей (нетelse), чтобы сделать код более совершенным.

if (!userInfo) {
  return;
}

if (!hasMoney) {
  return;
}

// 执行业务逻辑

элегантное условное суждение

простое суждениеif + returnвернулся рано. сложная логикаif else ifСпагетти-код недостаточно элегантен, хочу использоватьswitch case? Представляется, что реальная ситуацияif elseа такжеswitch caseРазница в использовании небольшая.

// if else
if (status == 1) {
  console.log('processing');
} else if (status == 2) {
  console.log('fail');
} else if (status == 3) {
  console.log('success');
} else if (status == 4) {
  console.log('cancel');
} else {
  console.log('other');
}

// switch case
switch (status) {
  case 1:
    console.log('processing');
    break;
  case 2:
    console.log('fail');
    break;
  case 3:
    console.log('success');
    break;
  case 4:
    console.log('cancel');
    break;
  default:
    console.log('other');
    break;
}

Как видно из приведенного выше кодаswitch caseСравниватьif elseТам больше строк кода,breakКлючевые слова также необходимы, не забудьте написатьdefault.这里我们推荐用ObjectилиMapСохранено как условие.

const actions = {
  1: 'processing',
  2: 'fail',
  3: 'success',
  4: 'cancel',
  default: 'other',
};

console.log(actions[status] ?? actions.default);

MapОн более мощный, ключ объекта может быть только строкой или символом, но ключ Карты может быть объектом или более, который можно использовать как условное совместное суждение.

const actions = new Map([
  [/^sign_[1-3]$/, () => 'A'],
  [/^sign_5$/, () => 'B'],
  //...
]);

const action = [...actions].filter(([key, value]) => key.test(`sign_${status}`));
action.forEach(([key, value]) => value());

Правильно используйте выражения

Правильно используйте выражения и избегайте спагетти-кода. Простые условные суждения можно заменить тернарным оператором. обычныйforможно использовать петлюmap,forEachзаменять.

уменьшить сложность

Чем больше строк кода в логике, тем сложнее ее поддерживать.На данный момент нам нужно извлечь связанную логику в другуюfunction, тем самым уменьшая сложность контекста. Здесь мы предлагаемfunctionОбъем кода не превышает одного экрана при ширине 120 символов.

Примечательно,functionЛучше всего контролировать заданные параметры в пределах 3, иначе поступающий заказ легко проигнорировать, что затрудняет его обслуживание. Если параметров слишком много, связанные параметры необходимо объединить в объекты и передать.

удалить повторяющийся код

дублировать код вBad Smellна первом месте, поэтому старайтесь избегать дублирования кода. Потому что это означает, что когда вам нужно изменить какую-то логику, будет несколько мест для изменения.

порядок введения

существуетimport, мы договорилисьnode_modulesПакеты в помещаются первыми, а затем пакеты с относительными путями. иногдаcssизimportДругой порядок приведет к разному приоритету выполнения.

использовать декларативный

Декларативное программирование: скажите «машине», чего вы хотите (что), и позвольте машине понять, как это сделать (как). Императивное программирование: приказывать «машине», как что-то делать, чтобы все, что вы хотите, она делала так, как вы ей приказываете. Мир прекрасен, избавьтесь от императива и сэкономьте время, чтобы испытать жизнь.

// 声明式:筛选我需要的结果
const result = dataSource.filter((dataItem) => dataItem.age > 10);

// 命令式:亲力而为查找/追加数据
let result = [];
dataSource.forEach((dataItem) => {
  if (dataItem.age > 10) {
    result.push(dataItem);
  }
});

В настоящее время некоторые люди скажут, что императивное программирование имеет хорошую производительность. На самом деле нам не нужно делать преждевременную оптимизацию при написании кода, и эта потеря производительности — капля в море по сравнению с ремонтопригодностью.

Пишите деловые заметки

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

функциональное программирование

Функциональное программирование привлекает все больше внимания, в том числеreactследуйте этой концепции.

Функции - это "граждане первого сорта"

Переменная может быть функцией и может использоваться в качестве аргумента другой функции.

function increaseOperator(user) {
  return user.age + 1;
}

userList.filter(Boolean).map(increaseOperator);

чистая функция

То есть один и тот же вход всегда будет получать один и тот же результат, и нет никаких наблюдаемых побочных эффектов. если используетсяsetTimeout,Promiseили более операций с неожиданными событиями. то такие операции называются "побочными эффектами"Effect.

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

// 不纯的, minimum 可能被其他操作改变
let minimum = 21;

function checkAge(age) {
  return age >= minimum;
}

// 纯的
function checkAge(age) {
  const minimum = 21;
  return age >= minimum;
}

Напримерsliceа такжеsplice,sliceОна соответствует определению чистой функции, потому что она гарантированно возвращает один и тот же результат для одного и того же ввода. а такжеspliceизменит массив, для которого он вызывается, что имеет наблюдаемый побочный эффект, заключающийся в том, что этот исходный массив постоянно изменяется.

var countList = [1, 2, 3, 4, 5];

// 纯的
countList.slice(0, 3);
//=> [1, 2, 3]

countList.slice(0, 3);
//=> [1, 2, 3]

// 不纯的
countList.splice(0, 3);
//=> [1, 2, 3]

countList.splice(0, 3);
//=> [4, 5]

неизменяемые данные

Каждая операция не изменяет исходное значение, а возвращает новое значение, не имеющее побочных эффектов. Неизменяемые модели данных легко отлаживать, не беспокоясь о том, что текущие данные будут изменены в другом месте.

// Bad 修改了参数
function updateUser(user) {
  user.age = 10;
}

// Good 返回新的对象
function updateUser(user) {
  return {
    ...user,
    age: 10,
  };
}

Рекомендуется здесьimmerРаботает как функциональные неизменяемые данные.

Полный тип ТС

typescriptИмеет сильную систему типов, которая компенсируетjavascriptШортборд по типу. мы пишемtypescriptПри кодировании будьте осторожны, чтобы не использовать неявные/явныеanyТип, если есть неопределенный тип, первое соображение泛型чтобы ограничить его, а затемunknownДобавьте утверждения и, наконец,any.

// 典型类型完备的函数
function pick<T, K extends keyof T>(obj: T, keys: K[]) {
  return Object.fromEntries(keys.map((key) => [key, obj[key]])) as Pick<T, K>;
}

pick(userInfo, ['email', 'name']);

Комбинировать красивее + eslint

При совместной работе единый код особенно важен.eslintПравила бесконечны. вeslint-config-airbnbСамый строгий и используется многими командами с открытым исходным кодом. Здесь мы можемprettierИспользуйте их вместе и отключите конфликтующие правила. Руководство по кодированиюGitHub.com/air не NB/Java…

Эпилог

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