19
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

team-lab-engineeringAdvent Calendar 2019

Day 2

知ってるとかっこよくなれるJS小技集2019

Last updated at Posted at 2019-12-01

はじめに

コードレビューでさらっと
「こんな書き方もできますよ」って言ってくれる先輩ってかっこいいですよね。
いつかそんな先輩になれるように、メモ化しておこうという試みです。クリスマスのお供にどうぞ。

記法

変数名が同じなら省略できる

const params = {
   id: id
   name: name
}
const params = {
   id,
   name
}

{}で分割代入

似てるものでこういう省略系もあります。分割代入と言うらしいです。

const id = response.id;
const {id} = response;

複数もOK

const {id, name} = response;

実務でよくみる使い方だと、Reactでpropsから値取り出すときとかでしょうか。

const {width, height} = props;
return (
  <div style={{ width, height }} />
)

スプレッド演算子...で展開できる

const hoge = {
    id: fuga.id,
    name: fuga.name,
    type: fuga.type
}
const hoge = {
    ...fuga
}

展開してさらに追加してもOK

const hoge = {
    ...fuga,
    date: Date.now()
}

実例だと、ReduxでStateを一部更新するときなんかに使えますね

  [HogeAction.SOMETHING]: (state: IHogeState, action: any): IHogeState => ({
    ...state,
    fuga: action.payload
  })

オブジェクトをコピーするためにも使えますが、Object.assign同様ディープコピーではないので注意です。

const original = {
   id: 1,
   obj: {
      name: "shwan"
   }
};

const copy = { ...original };
console.log(copy.obj.name); // "shwan"
original.obj.name = "changed";
console.log(copy.obj.name); // "changed"

オブジェクトのディープコピー技だとこんなのもありますが、undefindを扱えない罠があったりするので、できるだけ避ける人生を歩みたいですね。

const copy = JSON.parse(JSON.stringify(original));

スプレッド演算子に話をもどすと、引数でも展開できたりします。使う場面はあまりなさそうですが。

doSomething(fuga.id, fuga.name, fuga.type);
doSomething(...fuga);

条件分岐

論理演算子 || で条件分岐

let name;
if (response.name) {
    name = response.name
} else {
    name = 'Guest';
}
const name = response.name || 'Guest';

nullかもしれない配列を空配列にするときによく使います

response.names.forEach() // response.namesがnullやundefindだとエラー
const arr = response.names || [];
arr.forEach()

論理演算子 && で条件分岐

if (isGuest) {
    doSomething();
}
isGuest && doSomething();

この記法、 if( A && B ) if( A || B ) なときと違う動きをしてるようにも見えますが
&&左が偽なら左の値を、真なら右の値を返す
||左が真なら左の値を、偽なら右の値を返す
という共通の仕組みです。

const name = response.name || 'Guest';

の例ではresponse.name'shwan'などの文字列であれば左が真とみなせるので、左の値が返り、''nullであれば、偽なのでGuestが返ります。

キャスト

論理否定演算子 ! でのbooleanキャスト

const isSelected = this.state.type ? true : false;
const isSelected = !!this.state.type;

この記法も!を2つつなげると if(!isSelected) なときと違う用法にみえますが、
どちらも同じ論理否定演算子で、値を真偽値とみなしたうえで真偽を反転する という動きをしています。

+ でのnumberキャスト

const id = '1'
console.log(+id); // 1
console.log(new Date()); // Wed Nov 27 2019 21:00:38 GMT+0900 (日本標準時)
console.log(+new Date()); // 1574856056863

キャストできなければNaN になるので使い所は見きわめましょう。
ちなみにnew DateはDate.now()を使えばキャストせずとも数値で出せます。


console.log(Date.now()); // 1574856056863

letしない

三項演算子でletの回避

let type = 'a';
if (isB) {
    type = 'b';
}
const type = isB ? 'b' :'a';

即時関数でletの回避

複雑な分岐なら即時関数を使って回避することもできますね。このあたりは可読性とトレードオフでしょうか。

const type = ((flag) => {
  if (flag) {
    return 'a';
  } else {
    return fukuzatuNaSomething();
  }
})(isB);

その他Tips

関数の引数に初期値を設定する

初期値をつけておけば条件分岐を減らせます

const doSomething = (a, b = 1) => a * b;
doSomething(1); // 1
doSomething(1, 2); // 2

someで繰り返し処理を途中で抜ける

arr.forEach((obj) => {
  doSomething
  if(shouldBreak){
    //break; ←できない
  }
})
arr.some((obj) => {
  doSomething
  if (shouldBreak) {
    return true;
  }
  return false;
})

someで配列の中を調べる

includes代わりに使えます

const arr = ['a', 'b', 'c'];
arr.includes('b') // true
const arr = [{
  name: 'shwan'
},{
  name: 'taro'
}];
arr.some((person) => person.name === 'shwan') // true

対象が配列なのか調べる

Array.isArray(target)

対象がオブジェクトなのか調べる

Object.prototype.toString.call(target).slice(8, -1).toLowerCase() === 'object';

ここでいうオブジェクトは {id: 1, name:'a'} こういうのです。配列のようにスッキリは書けないので一工夫必要になります。

そろそろネタがなくなって極小ネタになってきたので、また来年に向けて溜め直してきます!

19
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?