SlideShare a Scribd company logo
Clean codeClean codeAdapted in JavaScript
Clean code in JavaScript
AgendaAgenda
Variables
Functions
Classes
Miscellaneous
VariablesVariables
There are only two hard things inThere are only two hard things in
Computer Science: cache invalidationComputer Science: cache invalidation
and naming things.and naming things.
There are only two hard things inThere are only two hard things in
Computer Science: cache invalidationComputer Science: cache invalidation
and naming things.and naming things.
“ Phil Karlton
Use meaningful and pronounceable variable namesUse meaningful and pronounceable variable names
const yyyymmdstr = moment().format('YYYY/MM/DD');
const yearMonthDay = moment().format('YYYY/MM/DD');
Use the same vocabulary for the same type of variableUse the same vocabulary for the same type of variable
getUserInfo();
getClientData();
getCustomerRecord();
getUser();
Use searchable namesUse searchable names
// What the heck is 525600 for?
for (let i = 0; i < 525600; i++) {
runCronJob();
}
// Declare them as capitalized `const` globals.
const MINUTES_IN_A_YEAR = 525600;
for (let i = 0; i < MINUTES_IN_A_YEAR; i++) {
runCronJob();
}
Keep convention in mindKeep convention in mind
class AnimalSoSweet {} // UpperCamelCase
let anAnimal = new AnimalSoSweet(); // LowerCamlCase
function sendARequest(requestToSend){};// LowerCamlCase
const NB_MS_IN_HOUR = 3600; // SCREAMING_SNAKE_CASE
Use explanatory variablesUse explanatory variables
const cityStateRegex = /^(.+)[,s]+(.+?)s*(d{5})?$/;
saveCityState(
cityStateRegex.match(cityStateRegex)[1],
cityStateRegex.match(cityStateRegex)[2]
);
const cityStateRegex = /^(.+)[,s]+(.+?)s*(d{5})?$/;
const match = cityStateRegex.match(cityStateRegex)
const city = match[1];
const state = match[2];
saveCityState(city, state);
Avoid Mental MappingAvoid Mental Mapping
const locations = ['Austin', 'New York', 'San Francisco'];
locations.forEach((l) => {
doStuff();
doSomeOtherStuff();
// ...
// ...
// ...
// Wait, what is `l` for again?
dispatch(l);
});
const locations = ['Austin', 'New York', 'San Francisco'];
locations.forEach((location) => {
doStuff();
doSomeOtherStuff();
// ...
// ...
// ...
dispatch(location);
});
Don't add unneeded contextDon't add unneeded context
const Car = {
carMake: 'Honda',
carModel: 'Accord',
carColor: 'Blue'
};
function paintCar(car) {
car.carColor = 'Red';
}
const Car = {
make: 'Honda',
model: 'Accord',
color: 'Blue'
};
function paintCar(car) {
car.color = 'Red';
}
Short-circuiting is cleaner than conditionalsShort-circuiting is cleaner than conditionals
function createMicrobrewery(name) {
let breweryName;
if (name) {
breweryName = name;
} else {
breweryName = 'Hipster Brew Co.';
}
}
function createMicrobrewery(name) {
const breweryName = name || 'Hipster Brew Co.'
}
FunctionsFunctions
Function arguments (2 or fewer ideally)Function arguments (2 or fewer ideally)
function createMenu(title, body, buttonText, cancellable) {
// ...
}
const menuConfig = {
title: 'Foo',
body: 'Bar',
buttonText: 'Baz',
cancellable: true
}
function createMenu(menuConfig) {
// ...
}
Functions should do one thing (Small !)Functions should do one thing (Small !)
function emailClients(clients) {
clients.forEach(client => {
const clientRecord = database.lookup(client);
if (clientRecord.isActive()) {
email(client);
}
});
}
function emailClients(clients) {
clients
.filter(isClientActive)
.forEach(email);
}
function isClientActive(client) {
const clientRecord = database.lookup(client);
return clientRecord.isActive();
}
Don't use flags as function parametersDon't use flags as function parameters
function createFile(name, temp) {
if (temp) {
fs.create('./temp/' + name);
} else {
fs.create(name);
}
}
function createFile(name) {
fs.create(name);
}
function createTempFile(name) {
createFile('./temp/' + name);
}
Function names should say what they doFunction names should say what they do
function dateAdd(date, month) {
// ...
}
const date = new Date();
/* It's hard to to tell from the
function name what is added
*/
dateAdd(date, 1);
function dateAddMonth(date, month) {
// ...
}
const date = new Date();
dateAddMonth(date, 1);
Function should not have side effectFunction should not have side effect
let name = 'Ryan McDermott';
function splitIntoFirstAndLastName() {
name = name.split(' ');
}
splitIntoFirstAndLastName();
function splitIntoFirstAndLastName(name) {
return name.split(' ');
}
const name = 'Ryan McDermott'
const newName = splitIntoFirstAndLastName(name);
Use default arguments instead of short circuitingUse default arguments instead of short circuiting
function writeForumComment(subject, body) {
subject = subject || 'No Subject';
body = body || 'No text';
}
function writeForumComment(
subject = 'No subject',
body = 'No text') {
// ...
}
Encapsulate conditionalsEncapsulate conditionals
if (fsm.state === 'fetching' && isEmpty(listNode)) {
// ...
}
function shouldShowSpinner(fsm, listNode) {
return fsm.state === 'fetching' && isEmpty(listNode);
}
if (shouldShowSpinner(fsmInstance, listNodeInstance)) {
// ...
}
Sort correctly callers and calleeSort correctly callers and callee
function doVerySpecificThing(){
//...
}
function doSpecificThing(){
//...
doVerySpecificThing();
}
function doThing(){
//...
doSpecificThing();
}
function doThing(){
//...
doSpecificThing();
}
function doSpecificThing(){
//...
doVerySpecificThing();
}
function doVerySpecificThing(){
//...
}
Prefer functional programming over imperativePrefer functional programming over imperative
const programmerOutput = [
{ name: 'Uncle Bobby', linesOfCode: 500 },
{ name: 'Suzie Q', linesOfCode: 1500 }
//....
];
let totalOutput = 0;
for (let i = 0; i < programmerOutput.length; i++) {
totalOutput += programmerOutput[i].linesOfCode;
}
const programmerOutput = [
{ name: 'Uncle Bobby', linesOfCode: 500 },
{ name: 'Suzie Q', linesOfCode: 1500 }
//....
];
const totalOutput = programmerOutput
.map((programmer) => programmer.linesOfCode)
.reduce((acc, linesOfCode) => acc + linesOfCode, 0);
Prefer polymorphism over lot of conditionalsPrefer polymorphism over lot of conditionals
class Airplane {
// ...
getCruisingAltitude() {
switch (this.type) {
case '777':
return this.getMaxAltitude() - this.getPassengerCount();
case 'Air Force One':
return this.getMaxAltitude();
case 'Cessna':
return this.getMaxAltitude() - this.getFuelExpenditure();
}
}
}
class Airplane {}
class Boeing777 extends Airplane {
getCruisingAltitude() {
return this.getMaxAltitude() - this.getPassengerCount();
}
}
class AirForceOne extends Airplane {
getCruisingAltitude() {
return this.getMaxAltitude();
}
}
Never everNever ever lets dead or commented code !!!lets dead or commented code !!!
// function oldRequestModule(url) {
// ...
// }
function newRequestModule(url) {
// ...
}
const req = newRequestModule;
inventoryTracker('apples', req, 'www.inventory-awesome.io');
function newRequestModule(url) {
// ...
}
const req = newRequestModule;
inventoryTracker('apples', req, 'www.inventory-awesome.io');
ClassesClasses
SSingle responsibilityingle responsibility
OOpen-closedpen-closed
LLiskov substitutioniskov substitution
IInterface segregationnterface segregation
DDependency injectionependency injection
SOLIDSOLID principlesprinciples
en.wikipedia.org/wiki/SOLID_(object-oriented_design)
Single Responsibility Principle (Single Responsibility Principle (SSRP)RP)
class UserService {
saveUser(user){
eventEmmitter.dispatch(ADD_USER, user);
return db.exec('INSERT VALUES ...', user);
}
}
class UserResource {
//...
save(user){
return db.exec('INSERT VALUES ...', user);
}
}
class UserService {
//...
saveUser(user){
eventEmmitter.dispatch(ADD_USER, user);
return userRessource.save(user)
}
}
"There should never be more than one reason for a class to change"
Open/Closed Principle (Open/Closed Principle (OOCP)CP)
class ExpenseController {
constructor() {}
addNewExpense(expense) {
if (this.validateExpense(expense)){
expenseService.save(expense);
}
}
validateExpense (expense){
return !!expense.description;
}
}
class UserAuth {
constructor(user) {
this.user = user;
}
verifyCredentials() {
// ...
}
}
class ExpenseController {
constructor(validators) {this.validators=validators;}
addNewExpense(expense) {
if (this.validateExpense(expense)){
expenseService.save(expense);
}
}
validateExpense (expense){
return this.validators.every(validator => {
return validator.isValid(expense));
});
}
}
"open for extension, but closed for modification"
Liskov substitution principle (Liskov substitution principle (LLSP)SP)
class Rectangle {
//...
setWidth(width) {
this.width = width;
}
setHeight(height) {
this.height = height;
}
getArea() {
return this.width * this.height;
}
}
class Square extends Rectangle {
// ...
setWidth(width) {
this.width = width;
this.height = width;
}
setHeight(height) {
this.width = height;
this.height = height;
}
}
function renderLargeRectangles(rectangles) {
rectangles.forEach((rectangle) => {
rectangle.setWidth(4);
rectangle.setHeight(5);
const area = rectangle.getArea();//Will return 25 for Square. Should be 20.
rectangle.render(area);
});
}
const rectangles = [new Rectangle(), new Rectangle(), new Square()];
renderLargeRectangles(rectangles);
Liskov substitution principle (Liskov substitution principle (LLSP)SP)
class Shape {
setColor(color) {
// ...
}
render(area) {
// ...
}
}
class Rectangle extends Shape {
constructor() {
super();
this.width = 0;
this.height = 0;
}
setWidth(width) {
this.width = width;
}
setHeight(height) {
this.height = height;
}
getArea() {
return this.width * this.height;
}
}
class Square extends Shape {
constructor() {
super();
this.length = 0;
}
setLength(length) {
this.length = length;
}
getArea() {
return this.length * this.length;
}
}
function renderLargeShapes(shapes) {
shapes.forEach((shape) => {
switch (shape.constructor.name) {
case 'Square':
shape.setLength(5);
break;
case 'Rectangle':
shape.setWidth(4);
shape.setHeight(5);
}
const area = shape.getArea();
shape.render(area);
});
}
Interface segregation principle (Interface segregation principle (IISP)SP)
class ACar {
run(){
throw new Error('SubType of car should implement run');
}
fillFuel(){
throw new Error('SubType of car should implement fillFuel');
}
}
class MyOldCar extends ACar{
run(){
// run ...
}
fillFuel(){
// handle fillFuel
}
}
class MyElectricCar extends ACar{
run(){
// run ...
}
fillFuel(){
// Not necessary
}
}
"Clients should not be forced to depend upon interfaces that they do not use."
Interface segregation principle (Interface segregation principle (IISP)SP)
class ACar {
run(){
throw new Error('SubType of car should implement run');
}
}
const FuelCar = (Superclass) => class extends Superclass {
fillFuel() {
throw new Error('SubType of FuelCar should implement fillFuel');
}
}
class MyOldCar extends FuelCar(ACar){
run(){
// run ...
}
fillFuel(){
// handle fillFuel
}
}
const ElectricCar = (Superclass) => class extends Superclass {
reload() {
throw new Error('SubType of ElectricCar should implement reload');
}
}
class MyElectricCar extends ElectricCar(ACar){
run(){
// run ...
}
reload(){
// handle reload
}
}
"Clients should not be forced to depend upon interfaces that they do not use."
Dependency Inversion Principle (Dependency Inversion Principle (DDIP)IP)
"1. High-level modules should not depend on low-level modules. Both should depend on abstractions.
2. Abstractions should not depend upon details. Details should depend on abstractions."
class UserController {
constructor(){
this.userService = new UserService();
}
save(user){
this.userService.save(user);
}
}
class UserController {
constructor(userService){
this.userService = userService;
}
save(user){
this.userService.save(user);
}
}
Use method chainingUse method chaining
"1. High-level modules should not depend on low-level modules. Both should depend on abstractions.
2. Abstractions should not depend upon details. Details should depend on abstractions."
class User {
constructor(name, age){
this.name = name;
this.age = age;
}
setName(name){
this.name = name;
}
setAge(age){
this.age = age;
}
}
const user = new User();
user.setName('Mathieu');
user.setAge('28');
class User {
constructor(name, age){
this.name = name;
this.age = age;
}
setName(name){
this.name = name;
return this;
}
setAge(age){
this.age = age;
return this;
}
}
const user = new User()
.setName('Mathieu')
.setAge('28');
MiscellaneousMiscellaneous   
Only comment things that have business logic complexity.Only comment things that have business logic complexity.
function hashIt(data) {
// The hash
let hash = 0;
// Length of string
const length = data.length;
// Loop through every character in data
for (let i = 0; i < length; i++) {
// Get character code.
const char = data.charCodeAt(i);
// Make the hash
hash = ((hash << 5) - hash) + char;
// Convert to 32-bit integer
hash &= hash;
}
}
"Comments are an apology, not a requirement. Good code mostly documents itself."
function hashIt(data) {
let hash = 0;
const length = data.length;
for (let i = 0; i < length; i++) {
const char = data.charCodeAt(i);
hash = ((hash << 5) - hash) + char;
// Convert to 32-bit integer
hash &= hash;
}
}
Bad commentsBad comments
/**
* 2016-12-20: Removed monads, didn't understand them (RM)
* 2016-10-01: Improved using special monads (JP)
* 2016-02-03: Removed type-checking (LI)
* 2015-03-14: Added combine with type-checking (JR)
*/
////////////////////////////////////////////////////////////////////////////////
// Scope Model Instantiation
////////////////////////////////////////////////////////////////////////////////
$scope.model = {
menu: 'foo',
nav: 'bar'
};
while (toto < MAX_VALUES){
if (test > MIN_VALUES){
} // if
} // while
FollowFollow
the cleanthe clean
code rulescode rules
slides.com/mbreton/clean-code-javascriptslides.com/mbreton/clean-code-javascript
github.com/ryanmcdermott/clean-code-javascriptgithub.com/ryanmcdermott/clean-code-javascript
Ad

More Related Content

What's hot (20)

Clean Code JavaScript
Clean Code JavaScriptClean Code JavaScript
Clean Code JavaScript
Riza Fahmi
 
Clean Code
Clean CodeClean Code
Clean Code
Victor Rentea
 
React + Redux for Web Developers
React + Redux for Web DevelopersReact + Redux for Web Developers
React + Redux for Web Developers
Jamal Sinclair O'Garro
 
9. ES6 | Let And Const | TypeScript | JavaScript
9. ES6 | Let And Const | TypeScript | JavaScript9. ES6 | Let And Const | TypeScript | JavaScript
9. ES6 | Let And Const | TypeScript | JavaScript
pcnmtutorials
 
React hooks
React hooksReact hooks
React hooks
Ramy ElBasyouni
 
Introduction to React JS for beginners
Introduction to React JS for beginners Introduction to React JS for beginners
Introduction to React JS for beginners
Varun Raj
 
Java 8 presentation
Java 8 presentationJava 8 presentation
Java 8 presentation
Van Huong
 
JSON: The Basics
JSON: The BasicsJSON: The Basics
JSON: The Basics
Jeff Fox
 
React lecture
React lectureReact lecture
React lecture
Christoffer Noring
 
JavaScript Tutorial
JavaScript  TutorialJavaScript  Tutorial
JavaScript Tutorial
Bui Kiet
 
Functional Domain Modeling - The ZIO 2 Way
Functional Domain Modeling - The ZIO 2 WayFunctional Domain Modeling - The ZIO 2 Way
Functional Domain Modeling - The ZIO 2 Way
Debasish Ghosh
 
An introduction to Google test framework
An introduction to Google test frameworkAn introduction to Google test framework
An introduction to Google test framework
Abner Chih Yi Huang
 
Workshop 21: React Router
Workshop 21: React RouterWorkshop 21: React Router
Workshop 21: React Router
Visual Engineering
 
Clean code and Code Smells
Clean code and Code SmellsClean code and Code Smells
Clean code and Code Smells
Mario Sangiorgio
 
How to go about testing in React?
How to go about testing in React? How to go about testing in React?
How to go about testing in React?
Lisa Gagarina
 
Resilience testing with Wiremock and Spock
Resilience testing with Wiremock and SpockResilience testing with Wiremock and Spock
Resilience testing with Wiremock and Spock
David Schmitz
 
An Introduction to ReactJS
An Introduction to ReactJSAn Introduction to ReactJS
An Introduction to ReactJS
All Things Open
 
JavaScript Tutorial For Beginners | JavaScript Training | JavaScript Programm...
JavaScript Tutorial For Beginners | JavaScript Training | JavaScript Programm...JavaScript Tutorial For Beginners | JavaScript Training | JavaScript Programm...
JavaScript Tutorial For Beginners | JavaScript Training | JavaScript Programm...
Edureka!
 
Clean code
Clean codeClean code
Clean code
Henrique Smoco
 
JavaScript - Chapter 9 - TypeConversion and Regular Expressions
 JavaScript - Chapter 9 - TypeConversion and Regular Expressions  JavaScript - Chapter 9 - TypeConversion and Regular Expressions
JavaScript - Chapter 9 - TypeConversion and Regular Expressions
WebStackAcademy
 
Clean Code JavaScript
Clean Code JavaScriptClean Code JavaScript
Clean Code JavaScript
Riza Fahmi
 
9. ES6 | Let And Const | TypeScript | JavaScript
9. ES6 | Let And Const | TypeScript | JavaScript9. ES6 | Let And Const | TypeScript | JavaScript
9. ES6 | Let And Const | TypeScript | JavaScript
pcnmtutorials
 
Introduction to React JS for beginners
Introduction to React JS for beginners Introduction to React JS for beginners
Introduction to React JS for beginners
Varun Raj
 
Java 8 presentation
Java 8 presentationJava 8 presentation
Java 8 presentation
Van Huong
 
JSON: The Basics
JSON: The BasicsJSON: The Basics
JSON: The Basics
Jeff Fox
 
JavaScript Tutorial
JavaScript  TutorialJavaScript  Tutorial
JavaScript Tutorial
Bui Kiet
 
Functional Domain Modeling - The ZIO 2 Way
Functional Domain Modeling - The ZIO 2 WayFunctional Domain Modeling - The ZIO 2 Way
Functional Domain Modeling - The ZIO 2 Way
Debasish Ghosh
 
An introduction to Google test framework
An introduction to Google test frameworkAn introduction to Google test framework
An introduction to Google test framework
Abner Chih Yi Huang
 
Clean code and Code Smells
Clean code and Code SmellsClean code and Code Smells
Clean code and Code Smells
Mario Sangiorgio
 
How to go about testing in React?
How to go about testing in React? How to go about testing in React?
How to go about testing in React?
Lisa Gagarina
 
Resilience testing with Wiremock and Spock
Resilience testing with Wiremock and SpockResilience testing with Wiremock and Spock
Resilience testing with Wiremock and Spock
David Schmitz
 
An Introduction to ReactJS
An Introduction to ReactJSAn Introduction to ReactJS
An Introduction to ReactJS
All Things Open
 
JavaScript Tutorial For Beginners | JavaScript Training | JavaScript Programm...
JavaScript Tutorial For Beginners | JavaScript Training | JavaScript Programm...JavaScript Tutorial For Beginners | JavaScript Training | JavaScript Programm...
JavaScript Tutorial For Beginners | JavaScript Training | JavaScript Programm...
Edureka!
 
JavaScript - Chapter 9 - TypeConversion and Regular Expressions
 JavaScript - Chapter 9 - TypeConversion and Regular Expressions  JavaScript - Chapter 9 - TypeConversion and Regular Expressions
JavaScript - Chapter 9 - TypeConversion and Regular Expressions
WebStackAcademy
 

Similar to Clean code in JavaScript (20)

Clean code
Clean codeClean code
Clean code
Arturo Herrero
 
ES6 Overview
ES6 OverviewES6 Overview
ES6 Overview
Bruno Scopelliti
 
Pro typescript.ch03.Object Orientation in TypeScript
Pro typescript.ch03.Object Orientation in TypeScriptPro typescript.ch03.Object Orientation in TypeScript
Pro typescript.ch03.Object Orientation in TypeScript
Seok-joon Yun
 
Hello Swift Final 5/5 - Structures and Classes
Hello Swift Final 5/5 - Structures and ClassesHello Swift Final 5/5 - Structures and Classes
Hello Swift Final 5/5 - Structures and Classes
Cody Yun
 
Architecting JavaScript Code
Architecting JavaScript CodeArchitecting JavaScript Code
Architecting JavaScript Code
Suresh Balla
 
Say It With Javascript
Say It With JavascriptSay It With Javascript
Say It With Javascript
Giovanni Scerra ☃
 
Wakanday JS201 Best Practices
Wakanday JS201 Best PracticesWakanday JS201 Best Practices
Wakanday JS201 Best Practices
Juergen Fesslmeier
 
Symfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technologySymfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technology
Daniel Knell
 
JavaScript Core
JavaScript CoreJavaScript Core
JavaScript Core
François Sarradin
 
JavaScript - Agora nervoso
JavaScript - Agora nervosoJavaScript - Agora nervoso
JavaScript - Agora nervoso
Luis Vendrame
 
Applying Real-time SQL Changes in your Hazelcast Data Grid
Applying Real-time SQL Changes in your Hazelcast Data GridApplying Real-time SQL Changes in your Hazelcast Data Grid
Applying Real-time SQL Changes in your Hazelcast Data Grid
Hazelcast
 
Object-Oriented JavaScript
Object-Oriented JavaScriptObject-Oriented JavaScript
Object-Oriented JavaScript
kvangork
 
Object-Oriented Javascript
Object-Oriented JavascriptObject-Oriented Javascript
Object-Oriented Javascript
kvangork
 
Thinking Functionally with JavaScript
Thinking Functionally with JavaScriptThinking Functionally with JavaScript
Thinking Functionally with JavaScript
Luis Atencio
 
AST - the only true tool for building JavaScript
AST - the only true tool for building JavaScriptAST - the only true tool for building JavaScript
AST - the only true tool for building JavaScript
Ingvar Stepanyan
 
JavaScript and UI Architecture Best Practices
JavaScript and UI Architecture Best PracticesJavaScript and UI Architecture Best Practices
JavaScript and UI Architecture Best Practices
Siarhei Barysiuk
 
Building Lithium Apps
Building Lithium AppsBuilding Lithium Apps
Building Lithium Apps
Nate Abele
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
Jonathan Wage
 
Dependency Management with RequireJS
Dependency Management with RequireJSDependency Management with RequireJS
Dependency Management with RequireJS
Aaronius
 
From android/ java to swift (2)
From android/ java to swift (2)From android/ java to swift (2)
From android/ java to swift (2)
allanh0526
 
Pro typescript.ch03.Object Orientation in TypeScript
Pro typescript.ch03.Object Orientation in TypeScriptPro typescript.ch03.Object Orientation in TypeScript
Pro typescript.ch03.Object Orientation in TypeScript
Seok-joon Yun
 
Hello Swift Final 5/5 - Structures and Classes
Hello Swift Final 5/5 - Structures and ClassesHello Swift Final 5/5 - Structures and Classes
Hello Swift Final 5/5 - Structures and Classes
Cody Yun
 
Architecting JavaScript Code
Architecting JavaScript CodeArchitecting JavaScript Code
Architecting JavaScript Code
Suresh Balla
 
Symfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technologySymfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technology
Daniel Knell
 
JavaScript - Agora nervoso
JavaScript - Agora nervosoJavaScript - Agora nervoso
JavaScript - Agora nervoso
Luis Vendrame
 
Applying Real-time SQL Changes in your Hazelcast Data Grid
Applying Real-time SQL Changes in your Hazelcast Data GridApplying Real-time SQL Changes in your Hazelcast Data Grid
Applying Real-time SQL Changes in your Hazelcast Data Grid
Hazelcast
 
Object-Oriented JavaScript
Object-Oriented JavaScriptObject-Oriented JavaScript
Object-Oriented JavaScript
kvangork
 
Object-Oriented Javascript
Object-Oriented JavascriptObject-Oriented Javascript
Object-Oriented Javascript
kvangork
 
Thinking Functionally with JavaScript
Thinking Functionally with JavaScriptThinking Functionally with JavaScript
Thinking Functionally with JavaScript
Luis Atencio
 
AST - the only true tool for building JavaScript
AST - the only true tool for building JavaScriptAST - the only true tool for building JavaScript
AST - the only true tool for building JavaScript
Ingvar Stepanyan
 
JavaScript and UI Architecture Best Practices
JavaScript and UI Architecture Best PracticesJavaScript and UI Architecture Best Practices
JavaScript and UI Architecture Best Practices
Siarhei Barysiuk
 
Building Lithium Apps
Building Lithium AppsBuilding Lithium Apps
Building Lithium Apps
Nate Abele
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
Jonathan Wage
 
Dependency Management with RequireJS
Dependency Management with RequireJSDependency Management with RequireJS
Dependency Management with RequireJS
Aaronius
 
From android/ java to swift (2)
From android/ java to swift (2)From android/ java to swift (2)
From android/ java to swift (2)
allanh0526
 
Ad

More from Mathieu Breton (8)

TDD in Javascript
TDD in JavascriptTDD in Javascript
TDD in Javascript
Mathieu Breton
 
Meet VueJs
Meet VueJsMeet VueJs
Meet VueJs
Mathieu Breton
 
FalcorJS
FalcorJSFalcorJS
FalcorJS
Mathieu Breton
 
BDD in Javascript
BDD in JavascriptBDD in Javascript
BDD in Javascript
Mathieu Breton
 
NodeJS Spring style Inversifyjs
NodeJS Spring style InversifyjsNodeJS Spring style Inversifyjs
NodeJS Spring style Inversifyjs
Mathieu Breton
 
Rollup.js
Rollup.jsRollup.js
Rollup.js
Mathieu Breton
 
Présentation de Dart
Présentation de DartPrésentation de Dart
Présentation de Dart
Mathieu Breton
 
JavaScript the-next-big...bytecode
JavaScript the-next-big...bytecodeJavaScript the-next-big...bytecode
JavaScript the-next-big...bytecode
Mathieu Breton
 
Ad

Recently uploaded (20)

Smart Investments Leveraging Agentic AI for Real Estate Success.pptx
Smart Investments Leveraging Agentic AI for Real Estate Success.pptxSmart Investments Leveraging Agentic AI for Real Estate Success.pptx
Smart Investments Leveraging Agentic AI for Real Estate Success.pptx
Seasia Infotech
 
Agentic Automation - Delhi UiPath Community Meetup
Agentic Automation - Delhi UiPath Community MeetupAgentic Automation - Delhi UiPath Community Meetup
Agentic Automation - Delhi UiPath Community Meetup
Manoj Batra (1600 + Connections)
 
IT484 Cyber Forensics_Information Technology
IT484 Cyber Forensics_Information TechnologyIT484 Cyber Forensics_Information Technology
IT484 Cyber Forensics_Information Technology
SHEHABALYAMANI
 
Reimagine How You and Your Team Work with Microsoft 365 Copilot.pptx
Reimagine How You and Your Team Work with Microsoft 365 Copilot.pptxReimagine How You and Your Team Work with Microsoft 365 Copilot.pptx
Reimagine How You and Your Team Work with Microsoft 365 Copilot.pptx
John Moore
 
AI 3-in-1: Agents, RAG, and Local Models - Brent Laster
AI 3-in-1: Agents, RAG, and Local Models - Brent LasterAI 3-in-1: Agents, RAG, and Local Models - Brent Laster
AI 3-in-1: Agents, RAG, and Local Models - Brent Laster
All Things Open
 
RTP Over QUIC: An Interesting Opportunity Or Wasted Time?
RTP Over QUIC: An Interesting Opportunity Or Wasted Time?RTP Over QUIC: An Interesting Opportunity Or Wasted Time?
RTP Over QUIC: An Interesting Opportunity Or Wasted Time?
Lorenzo Miniero
 
Mastering Testing in the Modern F&B Landscape
Mastering Testing in the Modern F&B LandscapeMastering Testing in the Modern F&B Landscape
Mastering Testing in the Modern F&B Landscape
marketing943205
 
Cybersecurity Threat Vectors and Mitigation
Cybersecurity Threat Vectors and MitigationCybersecurity Threat Vectors and Mitigation
Cybersecurity Threat Vectors and Mitigation
VICTOR MAESTRE RAMIREZ
 
Shoehorning dependency injection into a FP language, what does it take?
Shoehorning dependency injection into a FP language, what does it take?Shoehorning dependency injection into a FP language, what does it take?
Shoehorning dependency injection into a FP language, what does it take?
Eric Torreborre
 
Zilliz Cloud Monthly Technical Review: May 2025
Zilliz Cloud Monthly Technical Review: May 2025Zilliz Cloud Monthly Technical Review: May 2025
Zilliz Cloud Monthly Technical Review: May 2025
Zilliz
 
Everything You Need to Know About Agentforce? (Put AI Agents to Work)
Everything You Need to Know About Agentforce? (Put AI Agents to Work)Everything You Need to Know About Agentforce? (Put AI Agents to Work)
Everything You Need to Know About Agentforce? (Put AI Agents to Work)
Cyntexa
 
Optima Cyber - Maritime Cyber Security - MSSP Services - Manolis Sfakianakis ...
Optima Cyber - Maritime Cyber Security - MSSP Services - Manolis Sfakianakis ...Optima Cyber - Maritime Cyber Security - MSSP Services - Manolis Sfakianakis ...
Optima Cyber - Maritime Cyber Security - MSSP Services - Manolis Sfakianakis ...
Mike Mingos
 
GDG Cloud Southlake #42: Suresh Mathew: Autonomous Resource Optimization: How...
GDG Cloud Southlake #42: Suresh Mathew: Autonomous Resource Optimization: How...GDG Cloud Southlake #42: Suresh Mathew: Autonomous Resource Optimization: How...
GDG Cloud Southlake #42: Suresh Mathew: Autonomous Resource Optimization: How...
James Anderson
 
On-Device or Remote? On the Energy Efficiency of Fetching LLM-Generated Conte...
On-Device or Remote? On the Energy Efficiency of Fetching LLM-Generated Conte...On-Device or Remote? On the Energy Efficiency of Fetching LLM-Generated Conte...
On-Device or Remote? On the Energy Efficiency of Fetching LLM-Generated Conte...
Ivano Malavolta
 
AI Agents at Work: UiPath, Maestro & the Future of Documents
AI Agents at Work: UiPath, Maestro & the Future of DocumentsAI Agents at Work: UiPath, Maestro & the Future of Documents
AI Agents at Work: UiPath, Maestro & the Future of Documents
UiPathCommunity
 
fennec fox optimization algorithm for optimal solution
fennec fox optimization algorithm for optimal solutionfennec fox optimization algorithm for optimal solution
fennec fox optimization algorithm for optimal solution
shallal2
 
AI x Accessibility UXPA by Stew Smith and Olivier Vroom
AI x Accessibility UXPA by Stew Smith and Olivier VroomAI x Accessibility UXPA by Stew Smith and Olivier Vroom
AI x Accessibility UXPA by Stew Smith and Olivier Vroom
UXPA Boston
 
Bepents tech services - a premier cybersecurity consulting firm
Bepents tech services - a premier cybersecurity consulting firmBepents tech services - a premier cybersecurity consulting firm
Bepents tech services - a premier cybersecurity consulting firm
Benard76
 
An Overview of Salesforce Health Cloud & How is it Transforming Patient Care
An Overview of Salesforce Health Cloud & How is it Transforming Patient CareAn Overview of Salesforce Health Cloud & How is it Transforming Patient Care
An Overview of Salesforce Health Cloud & How is it Transforming Patient Care
Cyntexa
 
Limecraft Webinar - 2025.3 release, featuring Content Delivery, Graphic Conte...
Limecraft Webinar - 2025.3 release, featuring Content Delivery, Graphic Conte...Limecraft Webinar - 2025.3 release, featuring Content Delivery, Graphic Conte...
Limecraft Webinar - 2025.3 release, featuring Content Delivery, Graphic Conte...
Maarten Verwaest
 
Smart Investments Leveraging Agentic AI for Real Estate Success.pptx
Smart Investments Leveraging Agentic AI for Real Estate Success.pptxSmart Investments Leveraging Agentic AI for Real Estate Success.pptx
Smart Investments Leveraging Agentic AI for Real Estate Success.pptx
Seasia Infotech
 
IT484 Cyber Forensics_Information Technology
IT484 Cyber Forensics_Information TechnologyIT484 Cyber Forensics_Information Technology
IT484 Cyber Forensics_Information Technology
SHEHABALYAMANI
 
Reimagine How You and Your Team Work with Microsoft 365 Copilot.pptx
Reimagine How You and Your Team Work with Microsoft 365 Copilot.pptxReimagine How You and Your Team Work with Microsoft 365 Copilot.pptx
Reimagine How You and Your Team Work with Microsoft 365 Copilot.pptx
John Moore
 
AI 3-in-1: Agents, RAG, and Local Models - Brent Laster
AI 3-in-1: Agents, RAG, and Local Models - Brent LasterAI 3-in-1: Agents, RAG, and Local Models - Brent Laster
AI 3-in-1: Agents, RAG, and Local Models - Brent Laster
All Things Open
 
RTP Over QUIC: An Interesting Opportunity Or Wasted Time?
RTP Over QUIC: An Interesting Opportunity Or Wasted Time?RTP Over QUIC: An Interesting Opportunity Or Wasted Time?
RTP Over QUIC: An Interesting Opportunity Or Wasted Time?
Lorenzo Miniero
 
Mastering Testing in the Modern F&B Landscape
Mastering Testing in the Modern F&B LandscapeMastering Testing in the Modern F&B Landscape
Mastering Testing in the Modern F&B Landscape
marketing943205
 
Cybersecurity Threat Vectors and Mitigation
Cybersecurity Threat Vectors and MitigationCybersecurity Threat Vectors and Mitigation
Cybersecurity Threat Vectors and Mitigation
VICTOR MAESTRE RAMIREZ
 
Shoehorning dependency injection into a FP language, what does it take?
Shoehorning dependency injection into a FP language, what does it take?Shoehorning dependency injection into a FP language, what does it take?
Shoehorning dependency injection into a FP language, what does it take?
Eric Torreborre
 
Zilliz Cloud Monthly Technical Review: May 2025
Zilliz Cloud Monthly Technical Review: May 2025Zilliz Cloud Monthly Technical Review: May 2025
Zilliz Cloud Monthly Technical Review: May 2025
Zilliz
 
Everything You Need to Know About Agentforce? (Put AI Agents to Work)
Everything You Need to Know About Agentforce? (Put AI Agents to Work)Everything You Need to Know About Agentforce? (Put AI Agents to Work)
Everything You Need to Know About Agentforce? (Put AI Agents to Work)
Cyntexa
 
Optima Cyber - Maritime Cyber Security - MSSP Services - Manolis Sfakianakis ...
Optima Cyber - Maritime Cyber Security - MSSP Services - Manolis Sfakianakis ...Optima Cyber - Maritime Cyber Security - MSSP Services - Manolis Sfakianakis ...
Optima Cyber - Maritime Cyber Security - MSSP Services - Manolis Sfakianakis ...
Mike Mingos
 
GDG Cloud Southlake #42: Suresh Mathew: Autonomous Resource Optimization: How...
GDG Cloud Southlake #42: Suresh Mathew: Autonomous Resource Optimization: How...GDG Cloud Southlake #42: Suresh Mathew: Autonomous Resource Optimization: How...
GDG Cloud Southlake #42: Suresh Mathew: Autonomous Resource Optimization: How...
James Anderson
 
On-Device or Remote? On the Energy Efficiency of Fetching LLM-Generated Conte...
On-Device or Remote? On the Energy Efficiency of Fetching LLM-Generated Conte...On-Device or Remote? On the Energy Efficiency of Fetching LLM-Generated Conte...
On-Device or Remote? On the Energy Efficiency of Fetching LLM-Generated Conte...
Ivano Malavolta
 
AI Agents at Work: UiPath, Maestro & the Future of Documents
AI Agents at Work: UiPath, Maestro & the Future of DocumentsAI Agents at Work: UiPath, Maestro & the Future of Documents
AI Agents at Work: UiPath, Maestro & the Future of Documents
UiPathCommunity
 
fennec fox optimization algorithm for optimal solution
fennec fox optimization algorithm for optimal solutionfennec fox optimization algorithm for optimal solution
fennec fox optimization algorithm for optimal solution
shallal2
 
AI x Accessibility UXPA by Stew Smith and Olivier Vroom
AI x Accessibility UXPA by Stew Smith and Olivier VroomAI x Accessibility UXPA by Stew Smith and Olivier Vroom
AI x Accessibility UXPA by Stew Smith and Olivier Vroom
UXPA Boston
 
Bepents tech services - a premier cybersecurity consulting firm
Bepents tech services - a premier cybersecurity consulting firmBepents tech services - a premier cybersecurity consulting firm
Bepents tech services - a premier cybersecurity consulting firm
Benard76
 
An Overview of Salesforce Health Cloud & How is it Transforming Patient Care
An Overview of Salesforce Health Cloud & How is it Transforming Patient CareAn Overview of Salesforce Health Cloud & How is it Transforming Patient Care
An Overview of Salesforce Health Cloud & How is it Transforming Patient Care
Cyntexa
 
Limecraft Webinar - 2025.3 release, featuring Content Delivery, Graphic Conte...
Limecraft Webinar - 2025.3 release, featuring Content Delivery, Graphic Conte...Limecraft Webinar - 2025.3 release, featuring Content Delivery, Graphic Conte...
Limecraft Webinar - 2025.3 release, featuring Content Delivery, Graphic Conte...
Maarten Verwaest
 

Clean code in JavaScript

  • 5. There are only two hard things inThere are only two hard things in Computer Science: cache invalidationComputer Science: cache invalidation and naming things.and naming things. There are only two hard things inThere are only two hard things in Computer Science: cache invalidationComputer Science: cache invalidation and naming things.and naming things. “ Phil Karlton
  • 6. Use meaningful and pronounceable variable namesUse meaningful and pronounceable variable names const yyyymmdstr = moment().format('YYYY/MM/DD'); const yearMonthDay = moment().format('YYYY/MM/DD');
  • 7. Use the same vocabulary for the same type of variableUse the same vocabulary for the same type of variable getUserInfo(); getClientData(); getCustomerRecord(); getUser();
  • 8. Use searchable namesUse searchable names // What the heck is 525600 for? for (let i = 0; i < 525600; i++) { runCronJob(); } // Declare them as capitalized `const` globals. const MINUTES_IN_A_YEAR = 525600; for (let i = 0; i < MINUTES_IN_A_YEAR; i++) { runCronJob(); }
  • 9. Keep convention in mindKeep convention in mind class AnimalSoSweet {} // UpperCamelCase let anAnimal = new AnimalSoSweet(); // LowerCamlCase function sendARequest(requestToSend){};// LowerCamlCase const NB_MS_IN_HOUR = 3600; // SCREAMING_SNAKE_CASE
  • 10. Use explanatory variablesUse explanatory variables const cityStateRegex = /^(.+)[,s]+(.+?)s*(d{5})?$/; saveCityState( cityStateRegex.match(cityStateRegex)[1], cityStateRegex.match(cityStateRegex)[2] ); const cityStateRegex = /^(.+)[,s]+(.+?)s*(d{5})?$/; const match = cityStateRegex.match(cityStateRegex) const city = match[1]; const state = match[2]; saveCityState(city, state);
  • 11. Avoid Mental MappingAvoid Mental Mapping const locations = ['Austin', 'New York', 'San Francisco']; locations.forEach((l) => { doStuff(); doSomeOtherStuff(); // ... // ... // ... // Wait, what is `l` for again? dispatch(l); }); const locations = ['Austin', 'New York', 'San Francisco']; locations.forEach((location) => { doStuff(); doSomeOtherStuff(); // ... // ... // ... dispatch(location); });
  • 12. Don't add unneeded contextDon't add unneeded context const Car = { carMake: 'Honda', carModel: 'Accord', carColor: 'Blue' }; function paintCar(car) { car.carColor = 'Red'; } const Car = { make: 'Honda', model: 'Accord', color: 'Blue' }; function paintCar(car) { car.color = 'Red'; }
  • 13. Short-circuiting is cleaner than conditionalsShort-circuiting is cleaner than conditionals function createMicrobrewery(name) { let breweryName; if (name) { breweryName = name; } else { breweryName = 'Hipster Brew Co.'; } } function createMicrobrewery(name) { const breweryName = name || 'Hipster Brew Co.' }
  • 15. Function arguments (2 or fewer ideally)Function arguments (2 or fewer ideally) function createMenu(title, body, buttonText, cancellable) { // ... } const menuConfig = { title: 'Foo', body: 'Bar', buttonText: 'Baz', cancellable: true } function createMenu(menuConfig) { // ... }
  • 16. Functions should do one thing (Small !)Functions should do one thing (Small !) function emailClients(clients) { clients.forEach(client => { const clientRecord = database.lookup(client); if (clientRecord.isActive()) { email(client); } }); } function emailClients(clients) { clients .filter(isClientActive) .forEach(email); } function isClientActive(client) { const clientRecord = database.lookup(client); return clientRecord.isActive(); }
  • 17. Don't use flags as function parametersDon't use flags as function parameters function createFile(name, temp) { if (temp) { fs.create('./temp/' + name); } else { fs.create(name); } } function createFile(name) { fs.create(name); } function createTempFile(name) { createFile('./temp/' + name); }
  • 18. Function names should say what they doFunction names should say what they do function dateAdd(date, month) { // ... } const date = new Date(); /* It's hard to to tell from the function name what is added */ dateAdd(date, 1); function dateAddMonth(date, month) { // ... } const date = new Date(); dateAddMonth(date, 1);
  • 19. Function should not have side effectFunction should not have side effect let name = 'Ryan McDermott'; function splitIntoFirstAndLastName() { name = name.split(' '); } splitIntoFirstAndLastName(); function splitIntoFirstAndLastName(name) { return name.split(' '); } const name = 'Ryan McDermott' const newName = splitIntoFirstAndLastName(name);
  • 20. Use default arguments instead of short circuitingUse default arguments instead of short circuiting function writeForumComment(subject, body) { subject = subject || 'No Subject'; body = body || 'No text'; } function writeForumComment( subject = 'No subject', body = 'No text') { // ... }
  • 21. Encapsulate conditionalsEncapsulate conditionals if (fsm.state === 'fetching' && isEmpty(listNode)) { // ... } function shouldShowSpinner(fsm, listNode) { return fsm.state === 'fetching' && isEmpty(listNode); } if (shouldShowSpinner(fsmInstance, listNodeInstance)) { // ... }
  • 22. Sort correctly callers and calleeSort correctly callers and callee function doVerySpecificThing(){ //... } function doSpecificThing(){ //... doVerySpecificThing(); } function doThing(){ //... doSpecificThing(); } function doThing(){ //... doSpecificThing(); } function doSpecificThing(){ //... doVerySpecificThing(); } function doVerySpecificThing(){ //... }
  • 23. Prefer functional programming over imperativePrefer functional programming over imperative const programmerOutput = [ { name: 'Uncle Bobby', linesOfCode: 500 }, { name: 'Suzie Q', linesOfCode: 1500 } //.... ]; let totalOutput = 0; for (let i = 0; i < programmerOutput.length; i++) { totalOutput += programmerOutput[i].linesOfCode; } const programmerOutput = [ { name: 'Uncle Bobby', linesOfCode: 500 }, { name: 'Suzie Q', linesOfCode: 1500 } //.... ]; const totalOutput = programmerOutput .map((programmer) => programmer.linesOfCode) .reduce((acc, linesOfCode) => acc + linesOfCode, 0);
  • 24. Prefer polymorphism over lot of conditionalsPrefer polymorphism over lot of conditionals class Airplane { // ... getCruisingAltitude() { switch (this.type) { case '777': return this.getMaxAltitude() - this.getPassengerCount(); case 'Air Force One': return this.getMaxAltitude(); case 'Cessna': return this.getMaxAltitude() - this.getFuelExpenditure(); } } } class Airplane {} class Boeing777 extends Airplane { getCruisingAltitude() { return this.getMaxAltitude() - this.getPassengerCount(); } } class AirForceOne extends Airplane { getCruisingAltitude() { return this.getMaxAltitude(); } }
  • 25. Never everNever ever lets dead or commented code !!!lets dead or commented code !!! // function oldRequestModule(url) { // ... // } function newRequestModule(url) { // ... } const req = newRequestModule; inventoryTracker('apples', req, 'www.inventory-awesome.io'); function newRequestModule(url) { // ... } const req = newRequestModule; inventoryTracker('apples', req, 'www.inventory-awesome.io');
  • 27. SSingle responsibilityingle responsibility OOpen-closedpen-closed LLiskov substitutioniskov substitution IInterface segregationnterface segregation DDependency injectionependency injection SOLIDSOLID principlesprinciples en.wikipedia.org/wiki/SOLID_(object-oriented_design)
  • 28. Single Responsibility Principle (Single Responsibility Principle (SSRP)RP) class UserService { saveUser(user){ eventEmmitter.dispatch(ADD_USER, user); return db.exec('INSERT VALUES ...', user); } } class UserResource { //... save(user){ return db.exec('INSERT VALUES ...', user); } } class UserService { //... saveUser(user){ eventEmmitter.dispatch(ADD_USER, user); return userRessource.save(user) } } "There should never be more than one reason for a class to change"
  • 29. Open/Closed Principle (Open/Closed Principle (OOCP)CP) class ExpenseController { constructor() {} addNewExpense(expense) { if (this.validateExpense(expense)){ expenseService.save(expense); } } validateExpense (expense){ return !!expense.description; } } class UserAuth { constructor(user) { this.user = user; } verifyCredentials() { // ... } } class ExpenseController { constructor(validators) {this.validators=validators;} addNewExpense(expense) { if (this.validateExpense(expense)){ expenseService.save(expense); } } validateExpense (expense){ return this.validators.every(validator => { return validator.isValid(expense)); }); } } "open for extension, but closed for modification"
  • 30. Liskov substitution principle (Liskov substitution principle (LLSP)SP) class Rectangle { //... setWidth(width) { this.width = width; } setHeight(height) { this.height = height; } getArea() { return this.width * this.height; } } class Square extends Rectangle { // ... setWidth(width) { this.width = width; this.height = width; } setHeight(height) { this.width = height; this.height = height; } } function renderLargeRectangles(rectangles) { rectangles.forEach((rectangle) => { rectangle.setWidth(4); rectangle.setHeight(5); const area = rectangle.getArea();//Will return 25 for Square. Should be 20. rectangle.render(area); }); } const rectangles = [new Rectangle(), new Rectangle(), new Square()]; renderLargeRectangles(rectangles);
  • 31. Liskov substitution principle (Liskov substitution principle (LLSP)SP) class Shape { setColor(color) { // ... } render(area) { // ... } } class Rectangle extends Shape { constructor() { super(); this.width = 0; this.height = 0; } setWidth(width) { this.width = width; } setHeight(height) { this.height = height; } getArea() { return this.width * this.height; } } class Square extends Shape { constructor() { super(); this.length = 0; } setLength(length) { this.length = length; } getArea() { return this.length * this.length; } } function renderLargeShapes(shapes) { shapes.forEach((shape) => { switch (shape.constructor.name) { case 'Square': shape.setLength(5); break; case 'Rectangle': shape.setWidth(4); shape.setHeight(5); } const area = shape.getArea(); shape.render(area); }); }
  • 32. Interface segregation principle (Interface segregation principle (IISP)SP) class ACar { run(){ throw new Error('SubType of car should implement run'); } fillFuel(){ throw new Error('SubType of car should implement fillFuel'); } } class MyOldCar extends ACar{ run(){ // run ... } fillFuel(){ // handle fillFuel } } class MyElectricCar extends ACar{ run(){ // run ... } fillFuel(){ // Not necessary } } "Clients should not be forced to depend upon interfaces that they do not use."
  • 33. Interface segregation principle (Interface segregation principle (IISP)SP) class ACar { run(){ throw new Error('SubType of car should implement run'); } } const FuelCar = (Superclass) => class extends Superclass { fillFuel() { throw new Error('SubType of FuelCar should implement fillFuel'); } } class MyOldCar extends FuelCar(ACar){ run(){ // run ... } fillFuel(){ // handle fillFuel } } const ElectricCar = (Superclass) => class extends Superclass { reload() { throw new Error('SubType of ElectricCar should implement reload'); } } class MyElectricCar extends ElectricCar(ACar){ run(){ // run ... } reload(){ // handle reload } } "Clients should not be forced to depend upon interfaces that they do not use."
  • 34. Dependency Inversion Principle (Dependency Inversion Principle (DDIP)IP) "1. High-level modules should not depend on low-level modules. Both should depend on abstractions. 2. Abstractions should not depend upon details. Details should depend on abstractions." class UserController { constructor(){ this.userService = new UserService(); } save(user){ this.userService.save(user); } } class UserController { constructor(userService){ this.userService = userService; } save(user){ this.userService.save(user); } }
  • 35. Use method chainingUse method chaining "1. High-level modules should not depend on low-level modules. Both should depend on abstractions. 2. Abstractions should not depend upon details. Details should depend on abstractions." class User { constructor(name, age){ this.name = name; this.age = age; } setName(name){ this.name = name; } setAge(age){ this.age = age; } } const user = new User(); user.setName('Mathieu'); user.setAge('28'); class User { constructor(name, age){ this.name = name; this.age = age; } setName(name){ this.name = name; return this; } setAge(age){ this.age = age; return this; } } const user = new User() .setName('Mathieu') .setAge('28');
  • 37. Only comment things that have business logic complexity.Only comment things that have business logic complexity. function hashIt(data) { // The hash let hash = 0; // Length of string const length = data.length; // Loop through every character in data for (let i = 0; i < length; i++) { // Get character code. const char = data.charCodeAt(i); // Make the hash hash = ((hash << 5) - hash) + char; // Convert to 32-bit integer hash &= hash; } } "Comments are an apology, not a requirement. Good code mostly documents itself." function hashIt(data) { let hash = 0; const length = data.length; for (let i = 0; i < length; i++) { const char = data.charCodeAt(i); hash = ((hash << 5) - hash) + char; // Convert to 32-bit integer hash &= hash; } }
  • 38. Bad commentsBad comments /** * 2016-12-20: Removed monads, didn't understand them (RM) * 2016-10-01: Improved using special monads (JP) * 2016-02-03: Removed type-checking (LI) * 2015-03-14: Added combine with type-checking (JR) */ //////////////////////////////////////////////////////////////////////////////// // Scope Model Instantiation //////////////////////////////////////////////////////////////////////////////// $scope.model = { menu: 'foo', nav: 'bar' }; while (toto < MAX_VALUES){ if (test > MIN_VALUES){ } // if } // while
  翻译: