← Блог · · Команда ConvertCaseHQ · 6 мин чтения

camelCase и PascalCase: в чём разница?

Единственное различие между camelCase и PascalCase — первая буква. camelCase начинается со строчной и пишет с заглавной каждое следующее слово (userName, parseResponse). PascalCase пишет с заглавной каждое слово, включая первое (UserName, ResponseParser). По соглашению PascalCase обозначает типы (классы, интерфейсы, перечисления, компоненты React), а camelCase — значения и действия (переменные, функции, методы, свойства).

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

camelCase и PascalCase: коротко

camelCasePascalCase
Первая буквастрочнаязаглавная
Другие названияlowerCamelCase, mixedCase (PEP 8), camelCasing (Microsoft)UpperCamelCase, CapWords (PEP 8), StudlyCaps (PSR-1 в PHP), PascalCasing (Microsoft)
Чем обычно названыпеременные, функции, методы, свойства, параметрыклассы, интерфейсы, псевдонимы типов, перечисления, компоненты
ПримерыorderCount, sendInvoice()OrderService, InvoiceStatus

Читая руководства по стилю, следите за терминологией. Многие называют «camel case» оба стиля, а PEP 8 даже указывает CamelCase как другое название для CapWords — так там называется PascalCase. Если из текста руководства смысл неочевиден, смотрите на примеры.

Почему первая буква важна: типы и значения

Это соглашение позволяет читать код, ничего не выискивая. В const invoice = new Invoice(order) сразу видно, что Invoice — то, что вы создаёте, а invoice — то, что получили в результате. Так же работают сигнатуры TypeScript: в function total(order: Order): Money имя со строчной буквы — значение, а имена с заглавной — типы.

Кроме того, одно и то же слово может без конфликта называть и тип, и значение, а это случается постоянно: user: User, config: Config, request: Request. В языке, чувствительном к регистру, это разные идентификаторы, и заглавная буква подсказывает читателю, где что.

Где правило задаёт сам язык

В JavaScript, Java, C# и Python регистр имени класса — всего лишь соглашение. Ничто не мешает написать class invoice. В JavaScript соглашение можно превратить в проверку с помощью правила ESLint new-cap: по умолчанию оно отмечает new invoice(), а также вызов функции с заглавной буквы, например Invoice(), без new, что обычно оказывается ошибкой. Некоторые языки и фреймворки идут дальше и встраивают это правило в себя.

Go: первая буква определяет видимость

В Go нет ключевых слов public и private. Имя уровня пакета, поле структуры или метод экспортируются, если первая буква заглавная, и остаются приватными для своего пакета, если строчная. Выбирая между PascalCase и camelCase, вы выбираете видимость.

package shapes

import "math"

// Circle is exported, so other packages can use it.
type Circle struct {
	Radius float64 // exported field
	label  string  // unexported field
}

// Area is exported.
func Area(c Circle) float64 { return math.Pi * square(c.Radius) }

// square is unexported: only code inside package shapes can call it.
func square(x float64) float64 { return x * x }
c := shapes.Circle{Radius: 2}
fmt.Println(shapes.Area(c))   // fine
fmt.Println(shapes.square(2)) // compile error: square is not exported

Поэтому же Effective Go советует называть геттер для неэкспортируемого поля owner именем Owner, а не GetOwner. Заглавная буква и так говорит, что это публичный способ доступа.

React: компоненты пишутся с заглавной

Документация React говорит об этом прямо: имена компонентов должны начинаться с заглавной буквы, иначе они не будут работать. JSX считает тег со строчной буквы, например <section>, HTML-элементом, а тег с заглавной, например <OrderSummary />, — вашим компонентом.

Ruby: имена классов — это константы

В Ruby любое имя, начинающееся с заглавной буквы, — константа, а имена классов обязаны быть константами. class Invoice работает; class invoice — синтаксическая ошибка («class/module name must be CONSTANT»).

Что выбрать: язык за языком

  • JavaScript и TypeScript: camelCase для переменных, функций, методов и свойств; PascalCase для классов, интерфейсов, псевдонимов типов, перечислений и компонентов.
  • Java и Kotlin: такое же разделение плюс заглавные с подчёркиваниями для настоящих констант (MAX_RETRIES).
  • C#: PascalCase встречается гораздо чаще, чем в других языках. Методы, свойства, события, публичные поля, пространства имён и даже константы пишутся в PascalCase; camelCase — для параметров и локальных переменных, а _camelCase — для приватных полей. Типичная сигнатура выглядит так: public decimal CalculateTotal(decimal taxRate).
  • Swift: PascalCase для типов и протоколов, camelCase для всего остального.
  • Go: тот стиль, который соответствует нужной видимости.
  • Python: PascalCase только для классов. Функции и переменные пишутся в snake_case, а PEP 8 допускает camelCase лишь там, где он уже преобладает в старом коде.
  • PHP (PSR-1): классы в PascalCase, методы в camelCase.

О константах, файлах и всём остальном читайте в нашей шпаргалке по стилям именования для разработчиков.

Самое сложное: аббревиатуры

Как правильно: userId или userID? HttpClient или HTTPClient? Основные руководства по стилю отвечают по-разному:

РуководствоПравилоПримеры
Google (JavaScript, TypeScript, Java)Аббревиатуры пишутся как обычные словаxmlHttpRequest, customerId, loadHttpUrl
Microsoft .NETВ двухбуквенных аббревиатурах обе буквы заглавные; в более длинных заглавная только перваяIOStream, ioStream, HtmlTag
GoКаждая аббревиатура целиком в одном регистреServeHTTP, appID, xmlHTTPRequest
SwiftАббревиатуры, которые обычно пишут заглавными, пишутся либо целиком заглавными, либо целиком строчнымиutf8Bytes, userSMTPServer
RustАббревиатура считается одним словомUuid, Stdin
Python (PEP 8)В CapWords аббревиатура пишется целиком заглавнымиHTTPServerError
Airbnb JavaScriptЦеликом заглавными или целиком строчнымиSMSContainer, httpRequests

Наше мнение: если в руководстве для вашего языка есть правило, следуйте ему, потому что именно этого ждут стандартная библиотека и ваши коллеги. Если правила нет, пишите аббревиатуры как слова (HttpClient, userId). Так границы слов остаются видны, когда две аббревиатуры стоят рядом (сравните XMLHTTPRequest с XmlHttpRequest), а имена не ломаются при автоматическом преобразовании между стилями. Даже встроенный в браузер XMLHttpRequest смешивает оба подхода в одном имени.

Если хотите разобраться глубже, соглашения о регистре букв от Microsoft — хороший пример полного свода правил, изложенного на одной странице.

Как преобразовать camelCase в PascalCase и обратно

Для простого имени преобразование сводится к одному символу: смените регистр первой буквы.

const toPascal = (s) => s.charAt(0).toUpperCase() + s.slice(1);
const toCamel = (s) => s.charAt(0).toLowerCase() + s.slice(1);

toPascal("orderTotal"); // "OrderTotal"
toCamel("OrderTotal");  // "orderTotal"
toCamel("HTMLParser");  // "hTMLParser" (acronyms need a smarter split)

Последняя строка объясняет, почему инструменты сначала разбивают имена на слова. Вот что выдаёт конвертер регистра ConvertCaseHQ для нескольких неудобных случаев:

Исходный текстcamelCasePascalCase
user iduserIdUserId
XMLHttpRequestxmlHttpRequestXmlHttpRequest
getUserIDgetUserIdGetUserId
IOErrorioErrorIoError
iPhoneiPhoneIPhone

Конвертер разбивает имя по уже имеющимся заглавным и пишет аббревиатуры как слова, что совпадает с правилом Google. Если ваш проект следует правилам Go, .NET или PEP 8 для аббревиатур, поправьте такие имена вручную (в Go getUserId становится getUserID). Вторая ловушка — названия брендов: ни один алгоритм не знает, что IPhone выглядит неправильно.

Две частые ошибки

Первая — писать экземпляр с заглавной: const Cart = new ShoppingCart() делает Cart похожим на ещё один класс, и следующий читатель кода пойдёт искать его определение. Вторая — вспомогательная функция в PascalCase в JavaScript, например function FormatPrice(). Если это не конструктор и не компонент React, читатели решат, что ей нужен new или JSX, а new-cap будет ругаться, когда вы вызовете её без того и другого.

Эмпирическое правило

Если это тип или что-то, что вы создаёте через new, используйте PascalCase. Если это значение или действие — camelCase. Вопрос с аббревиатурами пусть решает руководство для вашего языка, а всё остальное пусть помнит линтер. Подробности для JavaScript, включая константы и приватные поля, — в нашем руководстве по именованию в JavaScript.