Phil Nash
Developer Advocate for Sonar
JavaScript | |
---|---|
1. | Using "var" instead of "let" or "const" |
2. | Complexity of functions is too high |
3. | Sections of code commented out |
4. | "==" and "!=" instead of "===" and "!==" |
5. | Unused assigments |
function sumOfPrimes(max) {
let total = 0;
for (let i = 2; i <= max; ++i) {
let prime = true;
for (let j = 2; j < i; ++j) {
if (i % j == 0) {
prime = false;
}
}
if (prime) {
total += i;
}
}
return total;
}
export function getWords(number) {
switch (number) {
case 1:
return "one";
case 2:
return "a couple";
case 3:
return "a few";
case 4:
return "many";
default:
return "lots";
}
}
function sumOfPrimes(max) { // +1
let total = 0;
for (let i = 2; i <= max; ++i) { // +1
let prime = true;
for (let j = 2; j < i; ++j) { // +1
if (i % j == 0) { // +1
prime = false;
}
}
if (prime) { // +1
total += i;
}
}
return total;
}
export function getWords(number) { // +1
switch (number) {
case 1: // +1
return "one";
case 2: // +1
return "a couple";
case 3: // +1
return "a few";
case 4: // +1
return "many";
default:
return "lots";
}
}
Cyclomatic complexity measures the number of paths through a function.
How do we measure understandability?
Creates a score by:
function sumOfPrimes(max) {
let total = 0;
for (let i = 2; i <= max; ++i) { // +1
let prime = true;
for (let j = 2; j < i; ++j) { // +2 (+1 for nesting)
if (i % j == 0) { // +3 (+2 for nesting)
prime = false;
}
}
if (prime) { // +2 (+1 for nesting)
total += i;
}
}
return total;
}
function getWords(number) {
switch (number) { // +1
case 1:
return "one";
case 2:
return "a couple";
case 3:
return "a few";
case 4:
return "many";
default:
return "lots";
}
}
for (...)
for (...)
for (...)
if (...)
for (...)
for (...)
for (...)
for (...)
for (...)
if (...)
for (...)
for (...)
Invert condition and early exit
Structural collapse
Extract a helper method
Other language features
function onSlideTransitionEnd({ currentSlide }) {
if ("confetti" in currentSlide.dataset) {
const defaults = { y: 0.5 };
if ("confettiSmall" in currentSlide.dataset) {
// Throw a small amount of confetti
} else if ("confettiLarge" in currentSlide.dataset) {
// Throw a large amount of confetti
} else {
// etc
}
}
}
function onSlideTransitionEnd({ currentSlide }) {
if (!("confetti" in currentSlide.dataset)) {
return;
}
const defaults = { y: 0.5 };
if ("confettiSmall" in currentSlide.dataset) {
// Throw a small amount of confetti
} else if ("confettiLarge" in currentSlide.dataset) {
// Throw a large amount of confetti
} else {
// etc
}
}
function onSlideTransitionEnd({ currentSlide }) {
if ("confetti" in currentSlide.dataset) {
if (window.matchMedia(`(prefers-reduced-motion: no-preference)`).matches) {
// Throw confetti
}
}
}
function onSlideTransitionEnd({ currentSlide }) {
if ("confetti" in currentSlide.dataset &&
window.matchMedia(`(prefers-reduced-motion: no-preference)`).matches) {
// Throw confetti
}
}
const particleCount = currentSlide.dataset["confettiParticleCount"]
? parseInt(currentSlide.dataset["confettiParticleCount"], 10)
: 200;
const duration = currentSlide.dataset["confettiDuration"]
? parseInt(currentSlide.dataset["confettiDuration"], 10)
: 0;
function integerDataAttrOrDefault(el, attr, def) {
return el.dataset[attr] ? parseInt(el.dataset[attr], 10) : def;
}
// later
const particleCount = integerDataAttrOrDefault(currentSlide, "confettiParticleCount", 200);
const duration = integerDataAttrOrDefault(currentSlide, "confettiDuration", 0);
const nestedProp = obj.first && obj.first.second;
const nestedProp = obj.first?.second;
const defaults = { y: 0.5 };
if (defaults.colors === undefined || defaults.colors === null) {
defaults.colors = arrayDataAttrOrDefault(currentSlide, "confettiColors", undefined);
}
const defaults = { y: 0.5 };
defaults.colors ??= arrayDataAttrOrDefault(currentSlide, "confettiColors", undefined);
const animalName =
pet.canBark() ?
pet.isScary() ?
'wolf'
: 'dog'
: pet.canMeow() ? 'cat'
: 'probably a bunny';
function animalName(pet) {
if (pet.canBark() && pet.isScary()) { return "wolf"; }
if (pet.canBark()) return "dog";
if (pet.canMeow()) return "cat";
return "probably a bunny";
}
Cognitive Complexity paper https://www.sonarsource.com/docs/CognitiveComplexity.pdf
Stop nesting ternaries https://www.sonarsource.com/blog/stop-nesting-ternaries-javascript/
🎉 Reveal.js Confetti 🎉
https://github.com/philnash/reveal-confetti