10 JavaScript and NodeJS Tips that Will Knock Away Multiple Concepts
Tags: react, javascript, webdev, node
Published: 2022-03-11 15:33:09


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jdd33ri83ev45lcf02tx.jpg)

Find me on [medium](https://medium.com/@jsmanifest)

While I was looking over some objects in JavaScript the other day I realized that choosing _what_ to learn is an effective way to take big leaps in the learning process. In todays world working smart is the way to go if you were to be doing something for the money. That is because value is the money maker. The more value something is to someone, the chances of that person paying for it increases dramatically.

When I look back into my beginning stages I was thankful for learning the `forEach`, `map`, `filter` and `reduce` _very early on_ in my career, because I _started seeing them everywhere_. I didn't know it at the time but learning them first was the smart thing to do. And I don't mean just looking at some documentation on how to use them. I read books that dove deep into those topics.

There's a difference between learning something like `reduce` as opposed to something like `map`. If I were to be asked which one I'd like to learn first and which one I'd push aside for later. I would choose `reduce` to get going with because mastering `reduce` will already help me become familiar with `filter` and `map` _at the same time_ since it can do both of them in the same function block:

```js
function filterInStrings(fn, arr) {
  return arr.filter((item) => {
    return typeof item === 'string'
  })
}

function mapToUppercase(fn, arr) {
  return arr.map((item) => item.toUpperCase())
}

// Achieves what filterInStrings and mapToUppercase does in one function block
function reduce(reducer, arr) {
  return arr.reduce((acc, item) => {
    if (typeof item === 'string') {
      return acc.concat(item.toUpperCase())
    }
    return acc
  })
}
```

This post will go over 10 JavaScript and NodeJS Tips that Knock Away Multiple Concepts with One Stone Each

## Request object (hint: `window.fetch`)

Ever used the [window.fetch](https://developer.mozilla.org/en-US/docs/Web/API/fetch) api in JavaScript when developing web applications? This popular function has two golden objects that I recommend learning _as soon as possible_.

The issue I see right now is that articles don't really go over these objects when they talk about the fetch api. Surely some will say read the response data by accessing the `body` property as well as the headers, but even knowing different _data types_ of the response data can go a long way. The [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) and [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response) object is _wrapped in every request_ you make.

When you learn the _Request_ interface you are actually hitting plenty of birds with one stone because when you venture out and get your hands dirty with third party tools available to the JavaScript community you will realize that this interface is purposely mimicked as a way to simplify (_and_ unify) all application development that work with the http request/response pipeline.

For example I use Gatsby Functions and the arguments they pass in to each function includes the [request](https://www.gatsbyjs.com/docs/reference/functions/getting-started/#introduction) object which is the [same as the object from the http module in nodejs](https://nodejs.org/api/http.html#http_class_http_incomingmessage).

Another example is [Web Workers](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers) in JavaScript. Workers are a hot feature in modern web applications which also uses the `fetch` api, where the `Request` object appears again.

## Response object (hint: `window.fetch`)

Just like the _Request_ object, the _Response_ object is just as (if not then more) important than the _Request_ object because this contains the most sensitive part of your application--the response _data_.

Once you get familiar with the Request and Response interface, you will have an easier time understanding documentations to third party tools.

For example, modern frameworks like GatsbyJS (again) mimic this structure in Gatsby Functions. ExpressJS is all about working with the _Request_ and _Response_ objects which is used by famous companies like Yahoo, Amazon, LinkedIn, The New York Times, The Home Depot, AT&T, Meetup, The Wall Street Journal, Docker, and many more (Source: [stackshare](https://stackshare.io/feed)).

I use AWS Lambda functions through the [@aws-sdk/client-lambda](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/clients/client-lambda/classes/lambda.html) SDK and see similar Request/Response objects with the same `body`, `headers`, `statusCode` properties when setting the `InvocationType` to `"RequestResponse"`

I also use Netlify Functions and the object you must return from each handler is the same shape you see from a `Response` with a statusCode that you must know to ensure the consumer handles it accordingly.

## Curry functions

Curry functions in JavaScript are functions that take one or more arguments at a time and returns a new function that expects the next (or remaining) arguments. It is a transformation of functions that returns new functions until all of the arguments are (expected to be) completed.

If you're a beginner in programming this might sound very odd. You'd most likely be asking yourself why anyone would ever return functions by giving functions. This is a different concept in the real world. If we want apples we don't want to have to give apples to get apples back. Why not just give the function and get what we need right away?

The benefits that currying provides is what makes libraries like [lodash](https://lodash.com/docs/4.17.15) so powerful. You can create a function that has some behavior predefined, then reuse it as a transformation for upcoming values (hint: even _*functions* are *treated as values*_ in JavaScript). [lodash-fp](https://github.com/lodash/lodash/wiki/FP-Guide) makes use of this pattern throughout all of their code and helps you work with a whole new programming paradigm.

Understanding currying is understanding _function composition_. When you spend lots of your time coming up with elegant ways to compose functions together you are already working with advanced concepts in one shot like lexical scoping, closures, higher order functions (the next section), execution contexts, passing `this` around correctly (if dependent), maintaining references, etc.

Here's what I mean:

```js
function curry(f) {
  const z = {}
  return function one(x, ...args) {
    return function two(y) {
      return f.call(one, x, y, z, ...args)
    }
  }
}
```

Here is all the things happening in this code snippet as the result of performing currying:

1. Higher order function
2. Lexical scoping
3. Closures
4. Maintaining references
5. Partial application
6. Maintaining `this` (if you intend to)
7. Hiding implementation details
8. Share the same object to all future functions to work with

A good example that makes great use of this technique is the [createStore](https://github.com/reduxjs/redux/blob/master/src/createStore.ts) function from the [redux](https://github.com/reduxjs/redux) library. (Hint: There are comments in that snippet that describe some neat behavior as the function is curried)

## Higher order functions

We previously talked about the benefits of curry functions. We also barely mentioned _higher order functions_.

By learning currying, you also learn working hands on with higher order functions, another big concept in JavaScript to make a big leap into your learning process.

When you learn higher order functions, you're also learning:

1. How to work with and how to _visualize_ closures
2. How to create partial application functions
3. How variables get memorized (which might help you understand memoization

Almost every JavaScript library out there works with higher order functions. It's what you can _do_ with higher order functions that matters most. If you can understand higher order functions, you're already on a good start to understanding how to do advanced techniques like [transducers](https://stackoverflow.com/questions/52274362/is-my-understanding-of-transducers-correct) in JavaScript.

## Stdout/Stdio/Stderr

Learning/working with `stdout`, `stderr` and `stdio` is probably a must if you like to develop applications on NodeJS (and even for web applications). This was something I didn't pay attention to much until later on in my development career.

Little did I know that I was working with `stdout` in [almost every single file](https://nodejs.org/dist/latest-v17.x/docs/api/console.html#new-consolestdout-stderr-ignoreerrors).

Understanding `stdout`, `stderr` and `stdio` and how it was being used in applications all of a sudden made a lot of concepts in magical frameworks "click" in my head when I first started focusing onto it awhile back.

Awhile back I was also planning to learn how the native `child_process` module in NodeJS works, but I kept pushing it aside. When I finally decided to get my hands dirty with it, I realized that `stdout` already knocked away the mysterious I had with the module. Then it was easy for me to get into tools like [Ink](https://github.com/vadimdemedes/ink).

## Promises (in conjunction with the callback concept)

Mastering promises and callbacks will improve your ability to work with asynchronous code. Callbacks and promises are _also everywhere_.

This should be one of the first things to master if you are a beginner. Your ability to debug also improves when dealing with complex code, like this annoying tricky code snippet that is presented commonly at interviews:

```js
const arr = [10, 12, 15, 21]
for (var i = 0; i < arr.length; i++) {
  setTimeout(function () {
    console.log('The index of this number is: ' + i)
  }, 3000)
}
```

## Thinking virtually

There's no doubt about it: thinking in virtual data structures is the way to go for modern application development. This is a concept popularized in [React](https://reactjs.org/) that inspired libraries like [virtual-dom](https://www.npmjs.com/package/virtual-dom) to provide more ways to write performant code for web apps.

When you start understanding the benefits and how working with virtual data structures is preferred over working directly with the DOM, you are already half way into understanding the modern techniques that power many of todays web applications. Some examples of such techniques are [rehydration](https://github.com/rt2zz/redux-persist) and [server components](https://reactjs.org/blog/2020/12/21/data-fetching-with-react-server-components.html).

Heck, thinking in virtual structures will even help your speed and ability to work directly with [AST](https://babeljs.io/docs/en/babel-types) structures. Ultimately your brain is just exercising so much on _just_ plain objects.

## Traversing/Playing with the DOM

Traversing the DOM correctly (in terms of correctly visiting children/parents in the expected order) will help prepare you understand several things:

1. How to work with ASTs (when you're comfortable working with ASTs you're pretty much comfortable working with creating your own babel plugins and/or working programmatically with tools like TypeScript)

2. How to understand ASTs

3. Tree traversal (You automatically understand traversing trees and how to collect results in a predictable manner). Don't be too scared about scary words like "depth first search" or "binary search", just think of what you do in the DOM when you traverse a DOM's descendants or ascendants. When you're new and someone tells you to start understanding tree traversal for interviews, you might feel overwhelmed because you don't even know where to start. Just start with the DOM. Don't overthink it too much.

4. How modern tools like [mdx](https://mdxjs.com/packages/react/) work beneath the surface.

## Spreading things

You can learn a few _very_ important concepts when you spend a lot of your time spreading things like so:

```js
function merge(obj1, obj2) {
  return { ...obj, ...obj2 }
}
```

By trial and error you will eventually come across errors where you wonder:

1. Why some objects aren't spreading and instead cause errors (Hint: `{ ...options.bar }` what if options.bar is not an object?)
2. Why some arrays aren't spreading and instead cause errors (Hint: `[...options.bar]` what if options.bar is not an array?)
3. Why `undefined` "spreads" into objects and `null` doesn't
4. How to "make" an object "spreadable" (Hint: The [iterable protocol](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#the_iterable_protocol), in other words work with the `[Symbol.iterator]`). This will will help you understand all of the above concepts

It's worth noting here that you might also want to understand that the alternative way of merging objects (`Object.assign`) silently causes side effects:

```js
const fruits = ['apple', 'banana']

const data = {
  carrots: [],
  get myFruits() {
    fruits.pop()
    return fruits
  },
  onion: 2,
}

const mergedData = Object.assign(data, {
  beverages: ['pepsi'],
})
```

Result (`myFruits` changed):

```json
{ "carrots": [], "myFruits": ["apple"], "onion": 2, "beverages": ["pepsi"] }
```

## Blob

Blobs are _everywhere_. They can be found in `window.fetch`, serialized into urls for `img` and `video`, uploading files, returned as a data type for some responses, etc.

Get familiar with working with `Blob`. This is the object that is used for online media sharing (such as images and videos), streaming, distributing files across networks, storing log files and updating them, file recovery, data storage (for analytical applications for example), as well as IoT (Internet of Things) applications.

## Conclusion

And that concludes the end of this post! I hope you have found valuable information here and look out for more from me in the future!

Find me on [medium](https://medium.com/@jsmanifest)