Javascriptに慣れてきたら覚えたい、可読性の低いかっこいい書き方


javascriptにそろそろ慣れてきました。
なので備忘録としてjsでよく見る、かっこいいけど初心者は意味不明な書き方というのを紹介したいと思います。
ついでに僕が考えた可読性が低いけどかっこいい感じの書き方とかも紹介したいと思います。

環境変数を読みこむ時とかに使うやつ

縦棒の「|」を使います、パイプと読みます。

const host = process.env.HOST || 'localhost'

hostという定数にはprocess.env.HOSTという環境変数が存在するならばprocess.env.HOSTの値が代入され、process.env.HOSTが存在しないならば'localhost'という文字列が代入されます。

三項演算子

はじめて見たときは、なんじゃこりゃってなるやつ第一位です。
以下の式はある数値が偶数かどうか判定するための式です、numの値が偶数ならばisEvenはtrue、奇数ならばisEvenはfalseになります

const num = 2
const isEven = num % 2 === 0 ? true : false
// isEvenはtrue

この書き方は以下の書き方のショートハンドです

const num = 2
let isEven
if (num % 2 === 0) {
  isEven = true
} else {
  isEven = false
}

三項演算子は以下の構造です

評価式 : 式がtrueの時に選択される値 ? 式がfalseの時に選択される値

三項演算子を使うことでコードがずっとコンパクトになり、さらにかっこいいです。
覚えましょう。

アロー関数

const doSomething = () => {
  /*
  何らかの処理
  */
}
array.forEach(value => {
  /*
  何らかの処理
  */
})

この書き方は以下の書き方のショートハンドです

const doSomething = function() {
  /*
  何らかの処理
  */
}
array.forEach(function(value) {
  /*
  何らかの処理
  */
})

はじめは混乱しますが慣れてくるとアロー関数ばっかり使うようになります。
普通の関数とアロー関数ではthisの扱いが違うのでその点だけは注意です。

if文の条件

if (isExist) {
  /*
  何らかの処理
  */
}

この書き方は以下の書き方のショートハンドです

if (isExist == true) {
  /*
  何らかの処理
  */
}

特に説明はありません。可読性高いやん。

mapとかで見るやつ

const array = [1, 2, 3].map((value) => value * 2 )
// arrayの中身は[2, 4, 6]

この書き方は以下の書き方のショートハンドです

const array = [1, 2, 3].map(value => {
  return value * 2
})

関数を囲む括弧{}を外すことでreturnを省略できるという書き方です。この書き方を使う場合は関数の中身が1行じゃないといけません。map、reduce、filter、findなどはループの処理結果を配列で返すのでreturnを使わないこの書き方をよく見ます。ちなみにforEachではあまり使いません。
filterだとこんな感じです。

const array = [1, 2, 3].filter((value) => value == 2 )
// arrayの中身は[2]

オブジェクトプロパティを指定して代入

const context = {
  data: {},
  header: {},
  response: {}
}

const { data, header, response } = context

この書き方は以下の書き方のショートハンドです

const context = {
  data: {},
  header: {},
  response: {}
}

const data = context.data
const header = context.header
const response = context.response

プロパティ名を省略してそのまま変数に打ち込めます。
axios使ってたりするとよく出てきます。

その場でpromiseを作ってその場で待つ

javascriptではsleepというものがありません。
なのでasync関数の中でsleep的な処理を書いてみます。

const asyncFunc = async () => {
  try {
    await new Promise(resolve => {
      setTimeout(() => {
        console.log('1')
        resolve()
      }, 5000)
    })
    console.log('2')
  } catch (error) {}
}
// 実行すると5秒後に1と表示されたあとに2が表示されます。

awaitで直接promiseがresoleveされるのを待つという荒業です。
ちなみに自分で思いついたのであまり洗練されているとは言えません。

ループの中でawait

みなさんループの中でawaitしたい場合はどうしているでしょうか?

// 適当なプロミスを返す関数
const doSomething = i => {
  return new Promise(resolve => {
    setTimeout(() => {
      console.log(`${i}番目の処理`)
      resolve()
    }, 1000)
  })
}

const asyncLoop = async () => {
  try {
    // 0から10の整数配列を作成
    const numArray = [...Array(10).keys()]
    // ループ処理の部分
    for (const i of numArray) {
      await doSomething(i)
    }
  } catch (error) {}
}

asyncLoop()

// 実行結果
// 0番目の処理
// 1番目の処理
// 2番目の処理
// 3番目の処理
// 4番目の処理
// 5番目の処理
// 6番目の処理
// 7番目の処理
// 8番目の処理
// 9番目の処理

forEachの中でawaitは使えないのでfor ofやfor inを使うのではないでしょうか?
ですが上記の場合だと実行が終わるのに10秒かかります.
Promise.allを使うと一気に実行するのでasyncLoopの中身を書き換えてみます。



const asyncLoop = async () => {
  try {
    // 0から10の整数配列を作成
    const numArray = [...Array(10).keys()]
    await Promise.all(numArray.map(i => doSomething(i)))
  } catch (error) {}
}

Promise.allは引数に配列を受け取るのでmapを使って配列を作ります。パッと見意味不明ですけどかっこいい。

また何か思いついたら書き足します