JavaScript で知っておきたい最新のテクニック [2021年版]

今やフロントエンド開発で欠かすことができない JavaScript ですが、ES2015以降、ECMAScript が毎年改定されるようになって様々な書き方が可能になってきています。ここではフロントエンジニアが知っておきたい JavaScript のモダンな書き方やテクニックをまとめてみました。

まとめて変数を定義する

let [a, b, c] = [1, 2, 3];

// これは以下と同じです.
let a, b, c;
a = 1;
b = 2;
c = 3;

分割代入する

分割代入ではプロパティ名とは異なる名前の変数に代入することもできます。

const rect = { width: 300, height: 200 };
const { width, height } = rect;
console.log(width); // 300

const { width: w, height: h } = rect;;
console.log(h); // 200

オブジェクトからプロパティを削除する

レスト演算子を利用するとオブジェクトから特定のプロパティを削除することができます。

const person = { firstName: 'Foo', lastName: 'Bar', age: 20 };
const { age: _, ...names } = person;
console.log(names); // { firstName: 'Foo', lastName: 'Bar' }

変数や配列を入れ替える

分割代入を利用すれば、一時変数を利用することなく変数や配列を入れ替えることができます。

let a = 'foo', b = 'bar';
[a, b] = [b, a];
console.log(a); // 'bar'

const arr = [1, 2, 3];
[arr[2], arr[1]] = [arr[1], arr[2]];
console.log(arr); // [1, 3, 2]

配列から重複する要素を除く

一意の値を格納することができる Set オブジェクトとスプレッド演算子を使うと、配列から重複する要素を取り除くことができます。

const arr = [1, 2, 3, 4, 2, 1, 3, 4, 1, 1];
const uniqueArr = [...new Set(arr)];
console.log(uniqueArr); // [1, 2, 3, 4]

元の配列に変更を加えることなく配列に要素を追加する

スプレッド演算子と配列の slice メソッドを使えば、元の配列に変更を加えることなく配列に要素を追加することができます。

const insert = (arr, i, value) => [ ...arr.slice(0, i), value, ...arr.slice(i)];

const arr = ['S', 'L', 'C', 'E'];
const result = insert(arr, 2, 'I');
console.log(result); // ['S', 'L', 'I', 'C', 'E']

配列をマージする

const merge = (a, b) => [...a, ...b];
const mergeWithoutDuplications = (a, b) => [...new Set([...a, ...b])];

const a = [1, 2, 3, 4];
const b = [4, 5];
console.log(merge(a, b)); // [1, 2, 3, 4, 4, 5]
console.log(mergeWithoutDuplications(a, b)); // [1, 2, 3, 4, 5]

オブジェクトのプロパティ名を動的にする

const type = 'id';
const item = {
  [type]: 'abcd01234';
};

console.log(item); // { id: 'abcd01234' }
console.log(item[type]); // 'abcd01234'
console.log(item['id']); // 'abcd01234'
console.log(item.id);    // 'abcd01234'

数字に変換する

+"13"  // 13
+true  // 1
+false // 0
+null  // 0

Number("13") // 13
Number("1.3") // 1.3
Number('foobar') // NaN

parseInt("1234", 10) // 1234
parseInt("1234 numbers", 10) // 1234
parseInt("numbers 1234", 10) // NaN
parseInt("98.76", 10) // 98

parseFloat("12.34") // 12.34
parseFloat("10.00") // 10

小数点以下を落とす

console.log(~~2.3 === 2); // true
console.log(~~(-2.3) === -2); // true

小数点第 n 位で四捨五入する

const round = (value, n) => Math.round(value * 10**n) / 10**n;

console.log(round(1.247, 1)); // 1.2
console.log(round(1.247, 2)); // 1.25

配列を for ループさせる

const animals = ["dog", "cat", "cow"];

for (let fruit of fruits) {
  // ...
}

論理AND演算子

condition && myFunc();

// これは以下と同じです.
if (condition) {
  myFunc();
}

配列をオブジェクトに変換する

const array = [1, 2, 3];
const object = { ...array };
console.log(object); // { 0: 1, 1: 2, 2: 3 }

プリミティブの型を取得する

const trueTypeOf = (obj) => Object.prototype.toString.call(obj).slice(8, -1).toLowerCase();

console.log(trueTypeOf('')); // string
console.log(trueTypeOf(0)); // number
console.log(trueTypeOf()); // undefined
console.log(trueTypeOf(null)); // null
console.log(trueTypeOf({})); // object
console.log(trueTypeOf([])); // array
console.log(trueTypeOf(0)); // number
console.log(trueTypeOf(() => {})); // function

console を使い分ける

console.table

const obj = {
  foo: 'bar',
  baz: 'qux',
};

console.log(obj); // Bad

console.table(obj); // Good
console.dir(obj); // Good

console.assert

// Bad
if (!isUserLoggedIn) {
  console.log("user is not logged in");
}

// Good
console.assert(isUserLoggedIn, "user is not logged in");

オブジェクトのプロパティ/メソッドのみをフィルターする

const store = {
  isInitialized: false,
  isFetching: false,
  fetch() {
    // ...
  }
};

const properties = Object.getOwnPropertyNames(store).filter(key => typeof store[key] !== "function");

console.log(properties); // ["isInitialized", "isFetching"]

const methods = Object.getOwnPropertyNames(store).filter(key => typeof store[key] === "function");

console.log(methods); // ["fetch"]

上記の方法では直接のメソッドだけを取得することができます。プロトタイプチェインをたどってすべてのメソッドを取得するには、もうひと手間加える必要があります。

const getMethods = (obj) => {
  let props = new Set();
  let o = obj;
  do {
    Object.getOwnPropertyNames(o)
      .filter(key => typeof obj[key] === 'function')
      .forEach(key => props.add(key));
  } while (o = Object.getPrototypeOf(o))
  return [...props.keys()];
}

console.log(getMethods("")); // ['constructor', 'anchor', 'big', ...]

ここでは Object.getPrototypeOf でプロトタイプチェインをたどって、メソッドを Set に追加しています。配列に追加するのではなく Set に追加しているのは、プロトタイプチェイン上に存在する、同名のメソッドの重複を避けるためです。

node_modules ディレクトリをまとめて削除する

以下のコマンドでコマンドを実行したディレクトリ以下を探索して node_modules を削除することができます。find . -name "node_modules" ... のようなコマンドを打つ必要はありません。

npx npkill

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です