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

Top comments (52)

Collapse
 
webjose profile image
José Pablo Ramírez Vargas

Couple of things:

  1. I'll never stop using 4 spaces.
  2. I'll use double quotes for strings when I'm adding a single quote in the text. const msg = "Why wouldn't I?";. const msg2 = 'Must I suffer because of someone else\'s preference by escaping the single quote everywhere?';
  3. Arrow functions are not always desirable because of their behavior with the this keyword. So no to that one too.

That's me. Problematic guy for sure. 😄

Collapse
 
brense profile image
Rense Bakker • Edited

You can also use template literals instead, if you need to use single or double quotes in a string.

const myString = `You'll be able to use any "quotes" here!`
Enter fullscreen mode Exit fullscreen mode
Collapse
 
stevetaylor profile image
Steve Taylor

How about using correct characters instead?

const msg = 'Why wouldn’t I?';
const msg2 = 'Must I suffer because of someone else’s preference by escaping the single quote everywhere?';
Enter fullscreen mode Exit fullscreen mode
Collapse
 
alexerdei73 profile image
AlexErdei73

I can't add too much to the code formatting question, because I use Prettier, which does the job. I think I use two spaces then Prettier does it better:) I never thought about it, it's in the muscle memory:)
The arrow function thing is interesting. The reason, why these were introduced to ES6, is that they do not bind the value of 'this' but inherit it. I have tiny code sample to show this in the arrow-function-example repository. The important point is that in some cases you should use arrow functions if you want to avoid binding 'this' explicitly in a regular function. It was important for some cases for event handling in React class components. Function components behave differently, so it's not so important in modern React. There are other cases, when you can't use arrow functions for the same reason. I met some cases when I used mongoose. There are cases, when arrow functions do not cause error, but not recommended for efficiency reasons. For example arrow functions shouldn't be used as methods in ES6 classes, because they become instance methods instead of prototype methods. In practice it means if you had 100 instances of the same objects the method is stored in the memory in all the 100 instances in the case of arrow function. In the case of the regular function the method is only stored once in the prototype object.

Collapse
 
darkwiiplayer profile image
𒎏Wii 🏳️‍⚧️ • Edited

Soft tabs with two spaces

It's been years and I have yet to see anyone make a coherent argument for spaces, or to even address the multitude of reasons why tabs are objectively better for indentation.

At this point I'm starting to think it's just clueless programmers intentionally placing hints in their code that it's not worth reading.

Never use semicolons

Every now and then you need semicolons to disambiguate your code though. "Never" and "Always" rules are just dumb. Know the language, and know when you need to use them, otherwise don't.

Always use single quotes

Quote styles is the dumbest red herring one could come up with. Who cares. Just be reasonably consistent within files and no sane person will care about it.

Avoid single letter names

Just avoid short names in general; query is still a bit short for my taste; it doesn't tell me what is being queried. The builtin browser APIs are doing this right: document.querySelectorAll tells you everything you need to know, even if you don't know that particular function.

Use the === operator

Again, this is a really dumb rule. Use whichever you need. Sometimes you may want ==, or you may know your input types.

Ternary operator single line only

I despise people who do this. It works for short conditions, like 1 and 2, but for longer expressions, it just makes the code much harder to read for no reason whatsoever. It's just making people's lives harder.

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

I like this example because it perfectly encapsulates why this sort of thing usually isn't a matter of how you format your code, but of how it's structured. Here's a better way of doing the same thing:

const validatePassword = password =>
   password.length >= 4 && /^(?=.*\d).{4,}$/.test(password)

if (validatePassword(password)) {
  ...
}
Enter fullscreen mode Exit fullscreen mode

All in all, these style guides always make me think if people put any degree of thought into how appropriate they are for collaborative projects, or just note down their personal preferred code style to lend it legitimacy and to push it onto others.

Collapse
 
jonrandy profile image
Jon Randy 🎖️

Tabs FTW 👍

Collapse
 
leob profile image
leob

Anything is fine with me, but a big, big, big no to tabs for indenting!

Do anything you want, I don't care, but tabs for indenting (or using any kind of non-printable characters in source code for that matter, except for linefeeds) are such a huge no-no for me.

Collapse
 
darkwiiplayer profile image
𒎏Wii 🏳️‍⚧️

...so you don't use spaces in your source code either?

Thread Thread
 
leob profile image
leob

Spaces are printable, I can clearly count the number of spaces (15) in this sentence :)

Thread Thread
 
darkwiiplayer profile image
𒎏Wii 🏳️‍⚧️

Here, count these:

Thread Thread
 
leob profile image
leob • Edited

Nice try lol, but the point was about printable/countable characters in my editor or in an IDE, not in a dev.to comment ... so, in my IDE I can press a key to move the cursor to the end of the line, which would shows me spaces there if any, and which would allow me to count them - UNLESS someone made the inane decision to use tabs.

(and most likely I'd have a setting in my IDE or editor to strip trailing spaces on save anyway)

I'll say it again - using TABs in source code is evil.

Thread Thread
 
darkwiiplayer profile image
𒎏Wii 🏳️‍⚧️

You're not making any sense. If you just feel an emotional attachment to spaces, then just say that. Making up incoherent excuses about counting spaces (wtf?) won't make using spaces any less annoying anyway.

Thread Thread
 
leob profile image
leob • Edited

Emotional attachment, "incoherent excuses", "I don't make any sense" - I think you're projecting there, you know about the pot and the kettle?

I'm just saying that for me tabs or other non-printable characters (with the exception of linefeeds) shouldn't be in source code, for practical (not for emotional) reasons. Just use tabs if you like, I don't care as long as I don't need to use your source code, lol.

Thread Thread
 
leob profile image
leob

P.S. what I dislike (I'm putting this politely) is that it goes against the grain of what at least 90% of devs are doing, and what I see in more than 95% of the codebases - spaces is the de facto standard, simple as that.

But no, "we" insist on doing things "our way", because we don't care about others, and we really love to make things more complicated and annoying for everyone else ... LOL !

Thread Thread
 
darkwiiplayer profile image
𒎏Wii 🏳️‍⚧️

I don't care much how people format their private code, I'm just opposed to using spaces in code that's meant for others to interact with, for a variety of reasons that amount to "It's not my business to dictate how others read code".

From the advocates of spaces, however, the only argument I have ever heard is an entitled notion of wanting to dictate how their code must look on other peoples' screens and the inability to configure their own editor.

So in short: Spaces are harmful, be a better person and use tabs.

That being said, this is of course a very minimal issue at the end of the day, and it's not like using spaces automatically makes anyone a monster; it's no more than a preventable annoyance.

Thread Thread
 
leob profile image
leob

When 95% (more, probably) of the devs and codebases are using spaces, not tabs, then spaces are the de facto standard. It doesn't really matter which is better - you're deviating from a de facto standard, which means you're the one who's upsetting and annoying, simple as that.

In many cases it doesn't matter what we do, all that matters is that we stick to doing the same thing in order to avoid friction and confusion. I'll leave it at that, use tabs in your private codebases, which I'll stay far away from.

Thread Thread
 
darkwiiplayer profile image
𒎏Wii 🏳️‍⚧️

I'm sorry, but if you think "Everyone does it" is a reasonable argument, then you have a lot of growing up to do before you're capable of having this discussion.

Thread Thread
 
leob profile image
leob

I do think it's a good argument, it's called "pragmatism" ... no comment on the 'growing up' thing, I'd say let's keep the ad hominems out of this discussion.

Thread Thread
 
darkwiiplayer profile image
𒎏Wii 🏳️‍⚧️ • Edited

Call it whatever you like, pragmatism, conformity, bob... It's still ultimately an appeal to popularity that makes no sense whatsoever. If there is a good reason to prefer spaces over tabs, then neither you nor anyone else I've met has been able to explain it so far.


Edit to add: And maybe don't try using big words like "ad hominem" when you don't actually know what they mean. It just makes you look worse.

Thread Thread
 
leob profile image
leob

LOL oh yes, you assume that I use the word "ad hominem", without knowing what it means - okay, I'll give you an example:

You said that I "have a lot of growing up to do" - that's an example of an ad hominem, you're targeting the person rather than the topic, got it?

Ohhhh but I use "ad hominem", but, I really don't know what it means - LOL !

P.S. by pragmatism I simply mean that if 95% or 99% of the world are using spaces, and if the pros or cons of spaces over tabs or the other way around are really marginal (which they are), then I'll use spaces simply in order not to complicate or to confuse matters or to annoy that vast majority of people by foisting my petty little preference on them - because it isn't worth it ... if the advantages of tabs over spaces would be significant and non-trivial then rest assured that I'd be the first one to adopt them.

Thread Thread
 
darkwiiplayer profile image
𒎏Wii 🏳️‍⚧️

LOL oh yes, you assume that I use the word "ad hominem", without knowing what it means - okay, I'll give you an example:

No, I am not assuming, I am telling you, because it is obvious from how you use the word that you have no actual understanding of what it means, and this comment confirms that once again.

And ironically, this just confirms my statement which you were complaining about: You still have a lot of growing up ahead of you before you're worth having any nuanced discussion with, if you think the best reaction to being told you're misunderstanding a word is to just double down and dig yourself in deeper.

pros or cons of spaces over tabs or the other way around are really marginal

The benefits of tabs aren't world-changing, but they are significant. Reading code with 2 spaces is a lot harder on my eyes than increasing that to just one more space, so for me being able to customise my indentation width is a huge improvement. If that's "marginal" to you, then congratulation, I can't force you to give a fuck about my problems, but I can insist that makes you a worse person.

foisting my petty little preference on them

That is literally what you're doing. I'm telling you: Let me choose my indentation width, and you are here crying and moaning about why I can't be allowed to read code the way I want it because a loud minority of people can't be fucking bothered to spend three minutes configuring their code editor. You're not advocating against "foistering preferences on others", you're advocating precisely for that.

if the advantages of tabs over spaces would be significant and non-trivial then rest assured that I'd be the first one to adopt them.

As we've established, your fellow programmers finding it easier to read your code isn't worth your time to consider, so I wonder what you would consider significant at this point. Presumably being cool and doing what everyone else does, as that is the only attempt at an argument I've seen from you.

Thread Thread
 
leob profile image
leob • Edited

I give up, this is hopeless. I'm not reading any new arguments, just repetition of previous statements with some haughty verbiage added in.

I gave you the most clearcut example of an "ad hominem": you're telling me that I have "growing up" to do, which means you're calling me immature. LOL - how much more of a clearcut example of an ad hominem so you want? I can't come up with a better example.

But no, you still maintain that I don't understand what the word means - it's just that you're not backing that up with any facts, you just repeat what you've already said. You're "not assuming", no you're "telling me" ...so that's the style of discussion we have here, dictates. Yes, you're "telling me" ... LOL.

I'm not going to waste time replying to the rest of the arguments, as all of it is heavily "the pot and the kettle" level stuff - you know that one, the pot and the kettle? Or you're again going to "tell me" that I don't understand what that means?

But hey I'm not taking any of this too seriously anyway, like most discussions here on dev.to it's mainly entertainment. People are taking themselves too seriously, putting themselves on some sort of comical pedestal.

I'll give you a clear example of being 'grown up': I'm going to wish you a nice day, and I genuinely mean it!

Thread Thread
 
darkwiiplayer profile image
𒎏Wii 🏳️‍⚧️

it's just that you're not backing that up with any facts

argumentum ad hominem:

  1. (Logic) fallacious argument that attacks not an opponent's beliefs but [their] motives or character
  2. (Logic) argument that shows an opponent's statement to be inconsistent with [their] other beliefs
  3. (Logic) an instance of either of these

thefreedictionary.com

an informal logical fallacy that occurs when someone attempts to refute an argument by attacking the claim-maker, rather than engaging in an argument or factual refutation of the claim.

Rational Wiki

The most common form of ad hominem is "A makes a claim x, B asserts that A holds a property that is unwelcome, and hence B concludes that argument x is wrong".

Wikipedia

And I'm sure you can find more if you google them. Have fun learning.

Thread Thread
 
leob profile image
leob

Hey whatever ... I think that "argument that attacks not an opponent's beliefs but [their] motives or character" comes close enough, mister would-be philosopher.

Have a nice day again, I think we can close this off now.

Thread Thread
 
darkwiiplayer profile image
𒎏Wii 🏳️‍⚧️

Not a mister, but okay :)

Thread Thread
 
leob profile image
leob

Ah apologies, hadn't really paid attention to your profile pic, my bad!

Collapse
 
jonrandy profile image
Jon Randy 🎖️

Tabs

Collapse
 
parimaldesign profile image
Parimal

What do I do If I am ugly ?

Collapse
 
darkwiiplayer profile image
𒎏Wii 🏳️‍⚧️

You compensate by writing pretty code instead, starting with using tabs 😉 😝

Collapse
 
webjose profile image
José Pablo Ramírez Vargas

Tabs are the incarnation from hell. Tabs makes your code look one way in editor A, but another way in editor B. Spaces is the only sane option! 😡

Thread Thread
 
darkwiiplayer profile image
𒎏Wii 🏳️‍⚧️

Tabs makes your code look one way in editor A, but another way in editor B.

There is exactly one person who has any business deciding what indentation level any code appears in in my editor, and that's me.

Everyone else has exactly the same authority over my preferred indentation level as over my colour theme. That's the whole point of tabs: You don't have to read my code in 3-space indentation if you don't want to, and I don't have to read yours in whatever you prefer.

Arguing for spaces is really just trying to shove ones preferred indentation level down everyone else's throat.

And I'm sorry but the "I'm too dumb to configure my editor" argument just doesn't make sense. Any modern code editor will let you change your tab width. This is extremely silly.

Thread Thread
 
webjose profile image
José Pablo Ramírez Vargas

I agree with your point in theory, but tooling in real life is not always helpful. You don't always have the ability to set your tab size in a tool. Spaces is the only sane path.

Thread Thread
 
darkwiiplayer profile image
𒎏Wii 🏳️‍⚧️

Call me idealistic, but I don't think bad tools should be an excuse for bad practices. It's the tools that need to change, not the code.

Thread Thread
 
webjose profile image
José Pablo Ramírez Vargas

I agree. The tools need changing. But I won't suffer while they decide to do it. So spaces.

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
 
zenneros profile image
Alejandro • Edited

I'll let semicolon as an option for the dev. About the rest, i'm agree with @brense about keeping a clear idea of what we're doing using both function keyword and getting the expressions into const. Good post btw 😁!

Collapse
 
corners2wall profile image
Corners 2 Wall

Not bad
I also use air-bnb style guide

Collapse
 
llorx profile image
Jorge Fuentes • Edited

Single quotes for strings is an aberration. In C, a char array would use double quotes and a single character would use single quotes. It matters a lot as they are 2 completely different definitions (zero ended uint8 array vs uint8).

If you are a decent old-school programmer, you will NEVER use single quotes for strings. The same for the semicolon. Optional semicolon is also an aberration decision for JS and not using it denotes a genZ that only knows JS, Python and maybe Java because of high school.

Damn late millenials... [Insert old man yelling at clouds gif here]

Collapse
 
brense profile image
Rense Bakker

Agree with everything except function expressions instead of declarations. Being concise is always better imho and using the function keyword is clearer than turning everything into an expression and assigning to const. Besides that, function declarations are also functionally different from function expressions in terms of scope.
Great article though, with good examples! 👍

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.