Naming Conventions
Be descriptive
Avoid single-letter names. Be descriptive with your naming. eslint: id-length
// bad
function q() {
// ...
}
// good
function query() {
// ...
}
camelCase for objects, functions, and instances
eslint: camelcase
// bad
const OBJEcttsssss = {};
const this_is_my_object = {};
function c() {}
// good
const thisIsMyObject = {};
function thisIsMyFunction() {}
PascalCase for constructors and classes
eslint: new-cap
// bad
function user(options) {
this.name = options.name;
}
const bad = new user({
name: 'nope',
});
// good
class User {
constructor(options) {
this.name = options.name;
}
}
const good = new User({
name: 'yup',
});
No leading or trailing underscores
eslint: no-underscore-dangle
JavaScript does not have private properties. A leading underscore implies privacy, but these properties are fully public and part of your API contract. Use WeakMap for true privacy instead.
// bad
this.__firstName__ = 'Panda';
this.firstName_ = 'Panda';
this._firstName = 'Panda';
// good
this.firstName = 'Panda';
// good, in environments where WeakMaps are available
const firstNames = new WeakMap();
firstNames.set(this, 'Panda');
Don’t save references to this
Use arrow functions or Function#bind instead.
// bad
function foo() {
const self = this;
return function () {
console.log(self);
};
}
// bad
function foo() {
const that = this;
return function () {
console.log(that);
};
}
// good
function foo() {
return () => {
console.log(this);
};
}
Filename matches default export
A base filename should exactly match the name of its default export.
// file 1 contents
class CheckBox {
// ...
}
export default CheckBox;
// file 2 contents
export default function fortyTwo() { return 42; }
// in some other file
// bad
import CheckBox from './checkBox'; // PascalCase import/export, camelCase filename
import FortyTwo from './FortyTwo'; // PascalCase import/filename, camelCase export
// bad
import CheckBox from './check_box'; // PascalCase import/export, snake_case filename
import forty_two from './forty_two'; // snake_case import/filename, camelCase export
// good
import CheckBox from './CheckBox'; // PascalCase export/import/filename
import fortyTwo from './fortyTwo'; // camelCase export/import/filename
camelCase for exported default functions
Your filename should be identical to your function’s name.
function makeStyleGuide() {
// ...
}
export default makeStyleGuide;
PascalCase for exported constructors, classes, and singletons
const AirbnbStyleGuide = {
es6: {
},
};
export default AirbnbStyleGuide;
Acronyms and initialisms
Acronyms and initialisms should always be all uppercased, or all lowercased.
Names are for readability, not to appease a computer algorithm. Full words are often clearest of all.
// bad
import SmsContainer from './containers/SmsContainer';
// bad
const HttpRequests = [
// ...
];
// good
import SMSContainer from './containers/SMSContainer';
// good
const HTTPRequests = [
// ...
];
// also good
const httpRequests = [
// ...
];
// best
import TextMessageContainer from './containers/TextMessageContainer';
// best
const requests = [
// ...
];
UPPERCASE constants
You may optionally uppercase a constant only if it meets all three conditions:
- It is exported
- It is declared with
const (cannot be reassigned)
- The programmer can trust it — and its nested properties — to never change
// bad — private to file, no need to uppercase
const PRIVATE_VARIABLE = 'should not be unnecessarily uppercased within a file';
// bad — this value is clearly meant to change
export const THING_TO_BE_CHANGED = 'should obviously not be uppercased';
// bad — let variables can be reassigned
export let REASSIGNABLE_VARIABLE = 'do not use let with uppercase variables';
// allowed but adds no semantic value
export const apiKey = 'SOMEKEY';
// better in most cases
export const API_KEY = 'SOMEKEY';
// bad — unnecessarily uppercases nested keys
export const MAPPING = {
KEY: 'value',
};
// good — uppercase the top-level export, lowercase the properties
export const MAPPING = {
key: 'value',
};
Accessors
Accessor functions are not required
Accessor functions for properties are not required.
Avoid JavaScript getters and setters
Do not use JavaScript get/set syntax. They cause unexpected side effects and are harder to test, maintain, and reason about. If you need accessor functions, use getVal() and setVal('hello') instead.
// bad
class Dragon {
get age() {
// ...
}
set age(value) {
// ...
}
}
// good
class Dragon {
getAge() {
// ...
}
setAge(value) {
// ...
}
}
Boolean accessors: isVal / hasVal
If the property or method returns a boolean, prefix it with is or has.
// bad
if (!dragon.age()) {
return false;
}
// good
if (!dragon.hasAge()) {
return false;
}
Generic get() / set() is fine — be consistent
It is okay to create generic get() and set() functions, but be consistent throughout the class.
class Jedi {
constructor(options = {}) {
const lightsaber = options.lightsaber || 'blue';
this.set('lightsaber', lightsaber);
}
set(key, val) {
this[key] = val;
}
get(key) {
return this[key];
}
}