DEV Community

Cover image for ๐Ÿ’…๐ŸปIf you're beautiful, follow this JS Code Style
Pulkit Singh
Pulkit Singh

Posted on

๐Ÿ’…๐ŸปIf you're beautiful, follow this JS Code Style

Image description

Summary ๐Ÿ“‘

Soft tabs with two spaces

Eslint: indent

  • Wrong:
if (true) {
    console.log('True')
}
Enter fullscreen mode Exit fullscreen mode
  • Correct:
if (true) {
  console.log('True')
}
Enter fullscreen mode Exit fullscreen mode

Never use semicolons

Eslint: semi

  • Wrong:
if (true) {
  console.log('True');
}
Enter fullscreen mode Exit fullscreen mode
  • Correct:
if (true) {
  console.log('True')
}
Enter fullscreen mode Exit fullscreen mode

Always use single quotes

Eslint: quotes

  • Wrong:
if (true) {
  console.log("True")
}
Enter fullscreen mode Exit fullscreen mode
  • Correct:
if (true) {
  console.log('True')
}
Enter fullscreen mode Exit fullscreen mode

Keep else in the same line of closure of the if

Eslint: brace-style

  • Wrong:
if (true) {
  console.log('True')
}
else {
  console.log('False')
}
Enter fullscreen mode Exit fullscreen mode
  • Correct:
if (true) {
  console.log('True')
} else {
  console.log('False')
}
Enter fullscreen mode Exit fullscreen mode

Add spaces between operators

Eslint: space-infix-ops

  • Wrong:
for (i=0;i<10;i++) {
  ...
}
Enter fullscreen mode Exit fullscreen mode
  • Correct:
for (i = 0; i < 10; i++) {
  ...
}
Enter fullscreen mode Exit fullscreen mode

Avoid single letter names

Be descriptive with your naming. Eslint: id-length

  • Wrong:
function q() {
  ...
}
Enter fullscreen mode Exit fullscreen mode
  • Correct:
function query() {
  ...
}
Enter fullscreen mode Exit fullscreen mode

Use lowerCamelCase

Eslint: camelcase

  • Wrong:
let is_error
Enter fullscreen mode Exit fullscreen mode
  • Correct:
let isError
Enter fullscreen mode Exit fullscreen mode

Use the === operator

Eslint: eqeqeq

  • Wrong:
const example = 'Is a example'

if (example == 15) {
  ...
}
Enter fullscreen mode Exit fullscreen mode
  • Correct:
const example = 'Is a example'

if (example === 15) {
  ...
}
Enter fullscreen mode Exit fullscreen mode

Add spaces outside parentheses () but avoid it inside

Eslint: keyword-spacing

  • Wrong:
if(condition){
  ...
}
Enter fullscreen mode Exit fullscreen mode
  • Correct:
if (condition) {
  ...
}
Enter fullscreen mode Exit fullscreen mode

Use function expressions instead of function declarations

Eslint: func-style

  • Wrong:
function foo() {
}
Enter fullscreen mode Exit fullscreen mode
  • Correct:
const foo = function () { }
Enter fullscreen mode Exit fullscreen mode

When you must use function expressions (as when passing an anonymous function), use arrow function notation

Eslint: prefer-arrow-callback

  • Wrong:
[1, 2, 3].map(function (x) {
  const y = x + 1
  return x * y
})
Enter fullscreen mode Exit fullscreen mode
  • Correct:
[1, 2, 3].map((x) => {
  const y = x + 1
  return x * y
})
Enter fullscreen mode Exit fullscreen mode

Ternary operator single line only

The ternary operator should be used on a single line.

  • Wrong:
const foo = (condition)
  ? 1
  : 2
Enter fullscreen mode Exit fullscreen mode
  • Correct:
const foo = (condition) ? 1 : 2
Enter fullscreen mode Exit fullscreen mode

Don't be dumb with ternary operator

Disallow ternary operators when simpler alternatives exist. Eslint: no-unneeded-ternary

  • Wrong:
const isYes = answer === 1 ? true : false;
Enter fullscreen mode Exit fullscreen mode
  • Correct:
const isYes = answer === 1;
Enter fullscreen mode Exit fullscreen mode

Use const for all of your references, avoid using var

Eslint: prefer-const

  • Wrong:
var foo = 'bar'
Enter fullscreen mode Exit fullscreen mode
  • Correct:
const foo = 'bar'
Enter fullscreen mode Exit fullscreen mode

If you must reassign references, use let instead of var

Eslint: no-var

  • Wrong:
var count = 1

if (condition) {
  count += 1
}
Enter fullscreen mode Exit fullscreen mode
  • Correct:
let count = 'bar'

if (condition) {
  count += 1
}
Enter fullscreen mode Exit fullscreen mode

Declare one const or let per declaration statement

Eslint: one-var

  • Wrong:
const foo = require('./bar'),
      foo = require('./foo')
Enter fullscreen mode Exit fullscreen mode
  • Correct:
const foo = require('./bar')
const foo = require('./foo')
Enter fullscreen mode Exit fullscreen mode

Use the literal syntax for object creation

Eslint: no-new-object

  • Wrong:
const foo = new Object()
Enter fullscreen mode Exit fullscreen mode
  • Correct:
const foo = {}
Enter fullscreen mode Exit fullscreen mode

Use the literal syntax for array creation

Eslint: no-array-constructuor

  • Wrong:
const foo = new Array()
Enter fullscreen mode Exit fullscreen mode
  • Correct:
const foo = []
Enter fullscreen mode Exit fullscreen mode

Declare array items in list

>= 4 arguments: indent. Eslint: array-element-newline and array-bracket-newline

  • Wrong:
const foo = [
  'hello', 'world'
]
Enter fullscreen mode Exit fullscreen mode
const foo = ['hello', 'world', 'lore', 'impsum']
Enter fullscreen mode Exit fullscreen mode
  • Correct:
const foo = ['hello', 'world']
Enter fullscreen mode Exit fullscreen mode
const foo = [
  'hello',
  'word',
  'lore', 
  'impsum'
]
Enter fullscreen mode Exit fullscreen mode

Function arguments indentation

>= 4 arguments: indent (excerpt callbacks brackets). Eslint: function-paren-newline

  • Wrong:
const foo = (
  'lore', 
  'impsum'
) => {}
Enter fullscreen mode Exit fullscreen mode
const foo = ('carls', 'farls', 'karen', 'logan') => {}
Enter fullscreen mode Exit fullscreen mode
foo.bar(
  'string',
  () => {
    statements
  }
)
Enter fullscreen mode Exit fullscreen mode
  • Correct:
const foo = ('lore', 'impsum') => {}
Enter fullscreen mode Exit fullscreen mode
const foo = (
  'carls', 
  'farls', 
  'karen',
  'logan'
) => {}
Enter fullscreen mode Exit fullscreen mode
foo.bar('string', () => {
  statements
})
Enter fullscreen mode Exit fullscreen mode

Method chaining

Eslint: newline-per-chained-call

  • Wrong:
user
.findOne({ name: 'foo' })
.populate('bar')
.exec(function(err, user) {
  return true
})
Enter fullscreen mode Exit fullscreen mode
user.findOne({ name: 'foo' })
  .populate('bar')
  .exec(function(err, user) {
    return true
  })
Enter fullscreen mode Exit fullscreen mode
  • Correct:
user
  .findOne({ name: 'foo' })
  .populate('bar')
  .exec(function(err, user) {
    return true
  })
Enter fullscreen mode Exit fullscreen mode

Any non-trivial conditions must be assigned to a variable or function with a descriptive name

  • Wrong:
if (password.length >= 4 && /^(?=.*\d).{4,}$/.test(password)) {
  ...
}
Enter fullscreen mode Exit fullscreen mode
  • Correct:
const isValidPassword = password.length >= 4 && /^(?=.*\d).{4,}$/.test(password)

if (isValidPassword) {
  ...
}
Enter fullscreen mode Exit fullscreen mode

Try to write comments that explain higher level mechanisms or clarify difficult segments of your code

  • Wrong:
const foo = "var(--bar)"

// Regexp
if (foo.replace(/var\(/, "").replace(/\)/, "") === "--bar") {
  ...
}
Enter fullscreen mode Exit fullscreen mode
  • Correct:
let foo = 'var(--bar)'

let value = foo
            .replace(/var\(/, '') // Remove the 'var('
            .replace(/\)/, '') // Remove the ')'

if (foo === '--bar') {
  ...
}
Enter fullscreen mode Exit fullscreen mode

Don't use comments to trivial things

  • Wrong:

// Create the passwors
const password = 'carls1234'
Enter fullscreen mode Exit fullscreen mode
  • Correct:
const password = 'carls1234'
Enter fullscreen mode Exit fullscreen mode

References

Project inspired by valle-style-guide

Latest comments (52)

Collapse
 
stevetaylor profile image
Steve Taylor

Two spaces arenโ€™t enough for readability. Itโ€™s a legacy code style from the bad old days of extremely nested callbacks.

Function expressions are ugly, verbose and unnecessary. Just use function foo() {/*...*/} at the top level. There's probably a good case for using function expressions where you need functions inside functions; in that case, use an arrow function to avoid this issues.

Collapse
 
dannyengelman profile image
Danny Engelman

Those are the best teachers.

They slap you in the face,

and never explain WHY you did it wrong.

Collapse
 
vaibhavkhulbe profile image
Vaibhav Khulbe

I am waiting for the post author to reply to the strong comments made by community members here. Let's see.

I just clicked this article thanks to DEV's newsletter they share (I don't know how they pick the articles) and was instantly in doubt as to how "If you are beautiful" and "follow this JS code style" can be together.

I skimmed for like 5 seconds and ranked it as a low-quality article as a DEV mod. I will be happy to change it to high-quality if I see some hard work in this piece.

Collapse
 
leob profile image
leob

Who says 4 spaces is wrong and 2 spaces is correct, or that we shouldn't use semicolons? Totally arbitrary.

Collapse
 
thethirdrace profile image
TheThirdRace • Edited

Who says 4 spaces is wrong and 2 spaces is correct

Young people that don't have eye problems... Then around 40 years old their eyes are not what they used to be and they need more than that measly 2 spaces to read the code properly. But then it would invalidate their crusade for the last 20 years so they keep repeating the dogma to justify their existence... ๐Ÿ˜’

or that we shouldn't use semicolons?

I'm a big fan of not using semicolons unless absolutely necessary because it's been proven times and times again that less noise in the code is better. It's a matter of eye pattern and keeping the attention of the dev on what matters. Semicolons mostly don't matter anymore and Prettier will add them when absolutely necessary.

It's all about accessibility and readability for everyone.

But... obviously, it's not a huge problem either. I've been in projects that used semicolons everywhere and it works just fine. The mental load of having semicolons is not problematic enough to make it a hill to die on... So even though there are benefits in avoiding semicolons unless necessary, realistically speaking I wouldn't impose it on people if they really hate it.

Collapse
 
johandalabacka profile image
Johan Dahl

There is two "standards" in javascript "standard" and "air-bnb". Use one or a variant of it but make the linter enforce these rules for everybody working on a project. I don't want a 1000+ line commit because all lines was suffixed with semicolons or the other way around. Any style I would call ugly is an unlinted frankensteinian stackoverflow cut and paste bonanza where you mix and match every and no style.

Collapse
 
brense profile image
Rense Bakker

theres also John Papa... I think even John Papa gave up on adding extra spaces everywhere possible though, so thats good. Guess hes pretty mainstream now :P

Collapse
 
gregorgonzalez profile image
Gregor Gonzalez

But I love new Array() ๐Ÿ˜ข

Collapse
 
rahulrajrd profile image
Rahul Raj

You should start using the semicolon

Collapse
 
codingjlu profile image
codingjlu

While I agree with most of the rules you included, this is highly opiniated and just your style, which you shouldn't impose upon others (I feel that's implied from "if you're beautiful"). Some things are 100% up to the programmer's personal taste, e.g. whether to use double quotes or semi colons.

I think one thing lacking from this article is why. Why should I follow those guidelines, and what benefits are there? Sure, I believe you should have meaningful variable names and spaces between operators, but does it actually matter whether you use double quotes or not? I feel like this guideline was formed solely for your visual pleasure in "beautifully formatted code".

Besides that, I think you could have simply left the article to Prettier or something. Just type your code and have Prettier do the annoying formatting for you. I like their presets anyways.

P.S. What do you have against functional declarations? In my opinion declaring the function as an expression looks really ugly and should only be done for arrow functions.

Collapse
 
udanielnogueira profile image
Daniel Nogueira

First time seeing about the 2 tabs, good to know it.

Collapse
 
joshistoast profile image
Josh Corbett

Been using all of these methods thanks to @antfu's eslint config :)