# Naming Convention
# Variables
A variable should be self-descriptive. It shouldn't be needed a comment for additional documentation:
```javascript
// bad
var value = 'John Smith';
var x = 'John Smith';
// good
var userName = 'John Smith';
```
Use camelCase to name variable:
```javascript
// bad
var firstname;
var first_name;
var FIRSTNAME;
var FIRST_NAME;
// good
var firstName;
```
> With exceptions for constants, privates, and classes/components.
## Variables: one letter variables
One letter is apropriate for loop counters and simple functions
```javascript=
for (let i=0; i<100; i++) {
...
}
let items = [{id: 1, name: 'John'}, {id: 2, name: 'Frank'}];
const filteredValues = items.filter(i => (i.name === 'John'));
```
## Variables: Boolean
Use prefix like _is_, _are_, or _has_ to distinguish a boolean from another variables by just looking at it:
```javascript
// bad
var activeUser = true;
var equal = false;
var loaded = true;
// good
var isActiveUser = true;
var areEqual = false;
var hasLoaded = true;
```
## Variables: Collections
Use plural to show that variable contains collection:
```javascript
// bad
var activeUser = [{id: 1, name: 'John Smith'}, {id: 2, name: 'Peter Strom'}];
var activeUserList = [{id: 1, name: 'John Smith'}, {id: 2, name: 'Peter Strom'},];
// good
var activeUsers = [{id: 1, name: 'John Smith'}, {id: 2, name: 'Peter Strom'}];
```
# Functions
Name functions in camel case.
> Best practices: tell what the function is doing by giving the function name a verb as prefix.
```javascript
// bad
function name(firstName, lastName) {
return `${firstName} ${lastName}`;
}
// good
function getName(firstName, lastName) {
return `${firstName} ${lastName}`;
}
```
> Best practices: if you doubt - favor descriptive over concise
```javascript
//bad
function filterUsers(conditions) {}
// good
function filterUsersByNameOrEmail(conditions) {}
```
> Best practices: do not use generic names for specific cases.
```javascript
// bad
function loadData() {}
// good
function loadPassengers() {}
```
# Factory
Even thought factory return object instances it is not constructor so name it as regular function but add suffix `Factory`
```javascript
// bad
const user = () => { ... }
const User = () => { ... }
const makeUser = () => { ... }
//good
const userFactory = () => { ... }
```
# Class
When constructor is called to instantiate a new instance of a class, its name should appear in Pascal Case, in contrast to other data structures:
```javascript
//bad
class user {
constructor(firstName, lastName) { ... }
}
var me = new user('John', 'Smith');
//good
class User {
constructor(firstName, lastName) { ... }
}
var me = new User('John', 'Smith');
```
## Class Members
Follow the same rules as for regular functions and variables - use self-descriptive names in camelCase
```
class User {
constructor(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
getFullName() {
return `${this.firstName} ${this.lastName}`;
}
}
```
## Class Members: Private
JS doesn't enforce access levels restrictions but you can mark "internal use only" properties and methods via undescore prefix.
Even though TS have level restriction support it is still good to have visual distinguish between public and private members
```
class User {
constructor(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
this.fullName = this._getFullName();
}
_getFullName() {
return `${this.firstName} ${this.lastName}`;
}
}
var user = new User('John', 'Smith');
// bad
console.log(user._getFullName());
// good
console.log(user.fullName);
```
# Component
Every time when component name appears in code it should be with capital first letter, no matter is it class-based or function-based component
```javascript
//bad
class user {
constructor({firstName, lastName}) { ... }
}
<user firstName="John" lastName="Smith"/>;
function user({firstName, lastName}) { ... }
<user firstName="John" lastName="Smith"/>;
//good
class User {
constructor({firstName, lastName}) { ... }
}
<User firstName="John" lastName="Smith"/>;
function User({firstName, lastName}) { ... }
<User firstName="John" lastName="Smith"/>;
```
#Global variables and constants
A global variables/constants are declared at the top of a file.
Use let and camelCase if it is mutable.
Use const and UPPERCASE with underscore if it is immutable.
Declare all const first.
```
// bad
const apiKey = '7dd791a7-cc5f-4534-8fa8-77e8b5b613bf';
let USER_PROFILE = await loadUserProfile();
// good
const API_KEY = '7dd791a7-cc5f-4534-8fa8-77e8b5b613bf';
let userProfile = await loadUserProfile();
```
# Acronims
Do not capitalize them, use rules for regular variables and constant.
Add short descriptive comment when you first introduce the abbreviation.
```javascript
// bad
const SPSLayout = (props) => {} //wtf is SPS?
// good
/**
* SPS - is short for `self profile setup`
*/
const SpsLayout = (props) => {}
```
# Events
Use past tense / passive voice for Events names.
Notify the world what happened, do not describe reaction - reaction on event could change during app lifetime.
```javascript
// bad
el.dispatchEvent('setUserName', query);
new CustomEvent('invalid', {value, error});
// good
el.dispatchEvent('userNameChanged', query);
new CustomEvent('validationFailed', {value, error});
```
# EventHandlers
## EventHandlers: emitter side
Use simple pattern `on${eventName}`. That helps to distinguish event handlers among other functions (renderProps for example)
```javascript
// bad
function Form({ processInvalid });
// good
function Form({ onValidationFailed });
```
## EventHandlers: subscriber side
Name in as `${eventName}Handler`
```javascript
// bad
function Form() {
const setAddress = (value) => {...}
};
// good
function Form() {
changeAddressHandler = (address) => {...}
};
```
# Store actions
Action - is an intention to change store, so use verb in infinitive form as first part for name.
```javascript
// bad
dispatcher('userName', query);
// good
dispatcher('setUserName', query);
```
# Typescript
## Interfaces and Types
Name it in PascalCase, do not use prefixes to make it special