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

Единственное различие между camelCase и PascalCase — первая буква. camelCase начинается со строчной и пишет с заглавной каждое следующее слово (userName, parseResponse). PascalCase пишет с заглавной каждое слово, включая первое (UserName, ResponseParser). По соглашению PascalCase обозначает типы (классы, интерфейсы, перечисления, компоненты React), а camelCase — значения и действия (переменные, функции, методы, свойства).
Одна эта заглавная буква несёт больше информации, чем кажется. Ниже — что она сообщает, в каких языках это обязательное правило, а не просто хороший тон, и в чём никто не может договориться: как писать аббревиатуры.
camelCase и PascalCase: коротко
| camelCase | PascalCase | |
|---|---|---|
| Первая буква | строчная | заглавная |
| Другие названия | 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 для нескольких неудобных случаев:
| Исходный текст | camelCase | PascalCase |
|---|---|---|
user id | userId | UserId |
XMLHttpRequest | xmlHttpRequest | XmlHttpRequest |
getUserID | getUserId | GetUserId |
IOError | ioError | IoError |
iPhone | iPhone | IPhone |
Конвертер разбивает имя по уже имеющимся заглавным и пишет аббревиатуры как слова, что совпадает с правилом 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.


