Constructors Should Start with an Uppercase Letter
What is it?
This practice enforces that constructor function names must begin with an uppercase letter. This naming convention acts as a reminder that a constructor function is meant to be invoked with the new keyword and distinguishes it from regular functions.
Why apply it?
Using a lowercase name for a constructor can lead to accidental calls of the function without the new keyword, which may result in unexpected behavior. Following this naming convention improves code clarity and reduces potential errors.
How to Fix it?
Ensure that the name of any function intended to be used as a constructor starts with an uppercase letter. Rename any misnamed constructor functions to clearly indicate their purpose and encourage proper instantiation using the new keyword.
Examples
Example 1:
Negative
Incorrect implementation that violates the practice.
namespace Models {
export function product(name: string, price: number, category: string) {
this.name = name;
this.price = price;
this.category = category;
this.getPriceWithTax = function(taxRate: number): number {
return this.price * (1 + taxRate);
};
}
}
const productInstance = (Models as any).product("Smartphone", 800, "Electronics"); // Noncompliant
console.log(productInstance ? productInstance.getPriceWithTax(0.2) : "No product created");
Example 2:
Positive
Correct implementation following the practice.
function Person(firstName: string, middleInitial: string, lastName: string) {
this.firstName = firstName;
this.middleInitial = middleInitial;
this.lastName = lastName;
this.getFullName = function(): string {
return `${this.firstName} ${this.middleInitial}. ${this.lastName}`;
};
}
const personInstance = new Person("John", "H", "Doe");
console.log(personInstance.getFullName());
Negative
Incorrect implementation that violates the practice.
function person(firstName: string, middleInitial: string, lastName: string) {
this.firstName = firstName;
this.middleInitial = middleInitial;
this.lastName = lastName;
this.getFullName = function(): string {
return this.firstName + " " + this.middleInitial + ". " + this.lastName;
};
}
const personInstance = person("Jane", "A", "Smith"); // Noncompliant: missing 'new'
console.log(personInstance);
Example 3:
Positive
Correct implementation following the practice.
namespace Models {
export function Product(name: string, price: number, category: string) {
this.name = name;
this.price = price;
this.category = category;
this.getPriceWithTax = function(taxRate: number): number {
return this.price * (1 + taxRate);
};
}
}
const productInstance = new (Models as any).Product("Laptop", 1200, "Electronics");
console.log(productInstance.getPriceWithTax(0.15));
Example 4:
Positive
Correct implementation following the practice.
class Employee {
employeeId: number;
name: string;
position: string;
constructor(employeeId: number, name: string, position: string) {
this.employeeId = employeeId;
this.name = name;
this.position = position;
}
getEmployeeDetails(): string {
return `ID: ${this.employeeId}, Name: ${this.name}, Position: ${this.position}`;
}
}
const emp = new Employee(123, "Alice", "Engineer");
console.log(emp.getEmployeeDetails());
Negative
Incorrect implementation that violates the practice.
function employee(employeeId: number, name: string, position: string) {
this.employeeId = employeeId;
this.name = name;
this.position = position;
this.getEmployeeDetails = function(): string {
return "ID: " + this.employeeId + ", Name: " + this.name + ", Position: " + this.position;
};
}
const emp = employee(456, "Bob", "Manager"); // Noncompliant: missing 'new'
console.log(emp ? emp.getEmployeeDetails() : "No employee created");