INTRODUCTION
This is the National Heritage Academies (NHA) School Applications Development team's coding standards page. Feel free to use these standards for your own reference. As the development team at NHA has grown over the past couple years so has the importance of common coding practices and standards. This article is meant to serve as the agreed upon standards to be followed by the NHA School Applications Development team. These standards are meant to help with:
- Keeping our code consistent
- Making our code easy to read and understand
- Making our code easier to maintain
The following sources were used to compile this list of standards.
GENERAL CODING STANDARDS
Always use semicolons (;)
Even though the semicolon is optional in JavaScript, we are choosing to end all statements with the semicolon. This is a consistent requirement across JavaScript, TypeScript, C#, and even SQL.
Always use curly braces around control structures.
Braces are required for all control structures (i.e. if, else, for, do, while, etc). Do use use single line if statements. The curly brace should start on the same line as the control structure and close on a new line. There should be a space before the opening curly brace.
Fail:
if (val == 2) doSomething();
if (val == 2)
doSomething();
if (val == 2)
doSomething();
else
doSomethingElse();
Pass:
if (val === 2) {
doSomething();
}
if (val == 2) {
doSomething();
} else {
doSomethingElse();
}
Try to reduce nesting
Nesting if statements within if statements can lead to messy, unreadable code. Always look for ways to avoid nesting if at all possible. Also try to avoid else if statements.
Fail:
if (myNumber > 0) {
if (myNumber > 100) {
if (!hasDiscountAlready) {
return addDiscountPercent(0);
} else {
return addDiscountPercent(10);
}
} else if (myNumber > 50) {
if (!hasDiscountAlready) {
return addDiscountPercent(5);
}
} else {
if (!hasDiscountAlready) {
return addDiscountPercent(0);
} else {
return addDiscountPercent(1);
}
}
} else {
error();
}
Pass:
if (myNumber <= 0) {
return error;
}
if (!hasDiscountAlready) {
return addDiscountPercent(0);
}
if (myNumber > 100) {
return addDiscountPercent(10);
}
if (myNumber > 50) {
return addDiscountPercent(5);
}
return addDiscountPercent(1);
Switch statements should use break and have a default
Try not to use switch statements, but if you must then make sure to each break condition and use default. Like if statements, the curly braces should start on the same line as the switch statement and end on a new line. There should be a space before the opening curly brace.
Fail:
switch (myNumber) {
case 10:
addDiscountPercent(0);
case 20:
addDiscountPercent(2);
case 30:
addDiscountPercent(3);
}
Pass:
switch (myNumber) {
case 10:
addDiscountPercent(0);
break;
case 20:
addDiscountPercent(2);
break;
case 30:
addDiscountPercent(3);
break;
default:
addDiscountPercent(0);
break;
}
Only use one variable per declaration
It is a cleaner and more understandable way to declare your variables.
Fail:
const a = 2, b = 3;
Pass:
const a = 2;
const b = 3;
TYPESCRIPT
The following rules are based on typescript but should also be followed where applicable to JavaScript.
When comparing use === instead of ==
Using === matches on both the type and value.
Fail:
if (val == 2)
Pass:
if (val === 2)
Never use var.
Use const for values that cannot be reassigned and let for anything else. Favor using const as much as possible.
Fail:
var value: number = 100;
Pass:
const value1: number = 100;
let value2: number = 200;
Always set the type for variables and properties.
Fail:
const value = 100;
class CarModel {
private _value = 100;
}
Pass:
const value: number = 100;
class CarModel {
private _value: number = 100;
}
Always set the return type for functions and class methods.
Fail:
function callback() {
return 'hello world';
}
class CarModel {
callback() {
return 'hello world';
}
}
Pass:
function callback(): string {
return 'hello world';
}
class CarModel {
callback(): string {
return 'hello world';
}
}
Always set the argument types for functions and class methods.
Fail:
function callback(inputStr) {
return inputStr;
}
class CarModel {
callback(inputStr) {
return inputStr;
}
}
Pass:
function callback(inputStr: string): string {
return inputStr;
}
class CarModel {
callback(inputStr: string): string {
return inputStr;
}
}
Avoid the use of any as a type as much as possible
Using any can allow for too many unknowns in what type of data you are dealing with. While it can't be avoided entirely, it should be very limited in its use.
Fail:
const value: any = 1;
Pass:
const value: number = 1;
Class Names should be in PascalCase format
Fail:
class carModel { }
Pass:
class CarModel { }
Class Property Definitions
Class properties should be listed before the constructor. Each property should be properly labeled private, protected, or public and listed in that order. Private properties should begin with an underscore and be camelCased. Protected and Public should simply be camelCased. It is preferrable to label public properties as such, but is not exactly required. It's preferred because by default non-labeled properties are considered public. However in C#, non-labeled properties are considered private. I think consistency across our two most used languages would be a good thing to pursue.
Fail:
class CarModel {
constructor() { }
TestPrivateProperty = 1;
TestProtectedProperty = true;
TestPublicProperty = 'I am public';
TestPublicProperty2 = 'So am I';
}
Pass:
class CarModel {
private _testPrivateProperty: number = 1;
protected testProtectedProperty: boolean = true;
public testPublicProperty: string = 'I am public';
testPublicProperty2: string = 'So am I';
constructor() { }
}
Class Method Definitions
Class methods should be camelCased. Each method should be properly labeled private, protected, or public with the exception of the constructor. It is preferrable to label public methods as such, but is not exactly required. It's preferred because by default non-labeled methods are considered public. However in C#, non-labeled methods are considered private. I think consistency across our two most used languages would be a good thing to pursue.
Also opening brackets are on the same line as the method name, and the closing bracket is on a new line.
Fail:
class CarModel {
TestPrivateMethod(): number {
return 1;
}
TestProtectedMethod(): boolean {
return true;
}
TestPublicMethod(): string {
return 'I am public';
}
TestPublicMethod2() {
return 'So am I';
}
}
Pass:
class CarModel {
private testPrivateMethod(): number {
return 1;
}
protected testProtectedMethod(): boolean {
return true;
}
public testPublicMethod(): string {
return 'I am public';
}
testPublicMethod2(): string {
return 'So am I';
}
}
C
The following rules are based on C#.
Class Names should be in PascalCase format
Fail:
class carModel { }
Pass:
class CarModel { }
Class Property Definitions
Class properties should be listed before the constructor. Each property should be properly labeled private, protected, or public and listed in that order. Private properties should begin with an underscore and be camelCased. Protected and Public should simply be PascalCased. It is preferrable to label private properties as such, but is not exactly required. It's preferred because by default non-labeled properties are considered private. However in TypeScript, non-labeled properties are considered public. I think consistency across our two most used languages would be a good thing to pursue.
Fail:
class CarModel {
CarModel() { }
int TestPrivateProperty = 1;
bool TestProtectedProperty = true;
string TestPublicProperty = 'I am public';
string TestPublicProperty2 = 'So am I';
}
Pass:
class CarModel {
private int _testPrivateProperty = 1;
protected bool TestProtectedProperty = true;
public string TestPublicProperty = 'I am public';
public string TestPublicProperty2 = 'So am I';
CarModel() { }
}
Class Method Definitions
Class methods should be PascalCased. Each method should be properly labeled private, protected, or public. It is preferrable to label private methods as such, but is not exactly required. It's preferred because by default non-labeled methods are considered private. However in TypeScript, non-labeled methods are considered public. I think consistency across our two most used languages would be a good thing to pursue.
Also, opening and closing brackets are on new lines.
Fail:
class CarModel {
int TestPrivateMethod() {
return 1;
}
bool TestProtectedMethod() {
return true;
}
string TestPublicMethod()
{
return 'I am public';
}
string TestPublicMethod2()
{
return 'So am I';
}
}
Pass:
class CarModel {
private int TestPrivateMethod()
{
return 1;
}
protected bool TestProtectedMethod()
{
return true;
}
public string TestPublicMethod()
{
return 'I am public';
}
public string TestPublicMethod2()
{
return 'So am I';
}
}
Conclusion
This is a work in process document. These standards and guidelines will change and evolve over time.
Top comments (0)