Skip to content

Commit 8c48ee6

Browse files
authored
Add a note about avoiding function hoisting #75
After discussions in dev meeting we decided to avoid hoisting to avoid confusion and PR back-and-forth. We tried adding a lint rule but it was overly aggressive so I'm adding a note here instead. Note: I removed/replaced some old content about the difference between function declarations and function expressions since it seems less relevant if we're avoiding hoisting. I'm happy to put it back in if others feel differently.
1 parent ee58a54 commit 8c48ee6

File tree

1 file changed

+60
-33
lines changed

1 file changed

+60
-33
lines changed

javascript/README.md

+60-33
Original file line numberDiff line numberDiff line change
@@ -759,44 +759,71 @@ function sayHi(name) {
759759

760760
## Functions
761761

762-
### 6.1 Function Style
762+
### 6.1 Avoid Function Hoisting
763763

764-
Understand the difference between **function declarations** and **function expressions**.
764+
Although it is possible to call functions before they are defined via [hoisting](https://developer.mozilla.org/en-US/docs/Glossary/Hoisting) we prefer to avoid this pattern in our code as it can be confusing.
765765

766-
> The primary difference between function declarations and function expressions is that declarations are hoisted to the top of the scope in which they are defined, which allows you to write code that uses the function before its declaration.
766+
#### Examples
767767

768-
It can be argued that using function expressions will result in more a structured code base. We do not have a strict rule of using function declarations vs function expressions but wanted to document the difference between the two.
768+
Although this code works properly it may be more confusing and we generally avoid it:
769769

770-
#### Examples
770+
```js
771+
logFoo();
772+
773+
function logFoo() {
774+
console.log("foo");
775+
}
776+
```
777+
778+
We would prefer one of the following patterns:
779+
780+
```js
781+
// Define the function before calling
782+
function logFoo() {
783+
console.log("foo");
784+
}
785+
786+
logFoo();
787+
```
788+
789+
```js
790+
// Import the function
791+
import {logFoo} from './log-foo.js';
771792

772-
> Function declarations in JavaScript are hoisted to the top of the enclosing function or global scope. You can use the function before you declared it:
773-
>
774-
> ```js
775-
> hoisted(); // logs "foo"
776-
>
777-
> function hoisted() {
778-
> console.log('foo');
779-
> }
780-
> ```
781-
782-
> Although this code might seem like an error, it actually works fine because JavaScript engines hoist the function declarations to the top of the scope. That means this code is treated as if the declaration came before the invocation.
783-
784-
> Note that function expressions are not hoisted:
785-
>
786-
> ```js
787-
> notHoisted(); // TypeError: notHoisted is not a function
788-
>
789-
> var notHoisted = function() {
790-
> console.log('bar');
791-
> };
792-
> ```
793-
794-
795-
### Resources
796-
797-
- MDN Web Docs
798-
- [Function Declaration]
799-
- [Function Expression]
793+
logFoo();
794+
```
795+
796+
In files that call a number of helper functions it can be helpful to move those functions to modules, or start the file with a main function that provides a summary of the steps taken in the file. For example:
797+
798+
```js
799+
// The `main` function contains an overview of the file's logic.
800+
// (`main` could be switched to a more meaningful name in context.)
801+
function main() {
802+
thing1();
803+
thing2();
804+
thing3();
805+
thing4();
806+
}
807+
808+
function thing1() {}
809+
function thing2() {}
810+
function thing3() {}
811+
function thing4() {}
812+
813+
main();
814+
```
815+
816+
Another option is to move helper functions to modules:
817+
818+
```js
819+
// Import helpers so they're defined up front
820+
import {thing1, thing2, thing3, thing4} from './helpers.js';
821+
822+
thing1();
823+
thing2();
824+
thing3();
825+
thing4();
826+
```
800827

801828
### 6.2 Function Arguments Parameter
802829

0 commit comments

Comments
 (0)