この記事はちょこちょこ修正しているため、「この記事は最終更新日からn年以上が経過しています。」の警告が出ませんし、いまでもLGTMをいただきますが、内容は2019年4月のものとなっています。JavaScriptの機能もそれから多く追加・修正されていることにご留意ください。
対象
- JavaScript 初心者
- キーを叩きすぎて手が痛くなってしまった人
- めんどくさがりの人
tl;dr
- コードゴルフにおいてショートハンドがよくつかわれますが、
ここでは可読性が高く、かつ文字数を少なくすることができるショートハンドを紹介します。 - もちろん可読性が高いというのは、人によって基準が異なるので、ここで紹介するのはあくまでも個人的なものです。
- 使いすぎてはいけません。コーディング規約があればそれを遵守しましょう。
条件分岐
ifの省略 (三項演算子)
const month = 5;
if (month >= 5) {
console.log("令和で、あります。");
} else {
console.log("平成で、あります。");
}
console.log(`${ month >= 5 ? "令和" : "平成" }で、あります。`);
ifの省略 (And演算子)
const isReiwa = true;
if (isReiwa) {
console.log("令和で、あります");
}
const isReiwa = true;
isReiwa && console.log("令和で、あります");
&&
の左側が truthy
と判定されるときに右側が実行される。
エルビス演算子やNull合体演算子の代わり
let v1 = "yeah!!!"
let v2;
console.log(v1 || "default"); //> "yeah!!!"
console.log(v2 || "default"); //> "default"
※注: 厳密には左側が falsy
に判定される場合に右側が返される。
falsy と判定される
false
""
NaN
0
undefined
null
(truthy
については上記以外)
そのため、次のような場合正常な動作が見込めない:
function rotate180(angle) {
// デフォルトで 90 をセット…???
angle = angle || 90;
const rotatedAngle = angle + 180;
if(rotatedAngle <= 360) {
return rotatedAngle;
} else {
return rotatedAngle - 360;
}
}
寒気がしますね(これは書かないと思いますが)。
このコードでの問題点は、angle
に 0
が渡されたとき、
次のように解釈されるからです。
/* 1 */ angle = angle || 90
/* 2 */ angle = 0 || 90 // 右側から評価を始める
/* 3 */ angle = false || 90 // `0` は `falsy`
/* 4 */ angle = 90 // 評価が右側に移る
つまり、 0
がセットできない ということです!!!
このような場合は、 パラメータの初期値 のセットを使いましょう。
ループ ※追記
for文で配列の全ての要素にアクセスして何かするパターンにおいて、for(~ of ~)
やforEach
メソッドを使うと漏れがなくループさせることができます。
const items = ["foo", "bar", "baz"];
for(let i = 0; i < items.length; ++i) {
console.log(items[i]);
}
これは以下のように変更できます
const items = ["foo", "bar", "baz"];
for(const item of items) {
console.log(item)
}
const items = ["foo", "bar", "baz"];
items.forEach(item => console.log(item));
要素にアクセスする[i]
を忘れるミスだったり、forの条件の書き方を間違えたりループ内でi
に代入したりするミスによって無限ループしたり全ての要素にアクセスできなかったりするという地獄から解放されます。ついでにタイプ数が少ないので指が痛くなりません。
関数
アロー関数
const doSomething = function(input) {
return input - 2018;
};
phase1
const doSometing = (input) => {
return input - 2018;
};
function式
と アロー関数
は完全に同じではありません。
(this
が束縛されない・prototype
がない…)
パフォーマンス等によってアロー関数のほうが優れている場合があります。
phase2 (引数、処理部分のかっこを省略)
const doSomething = input => input - 2018;
アロー関数では、
- 引数が1つしかない場合、引数を囲むかっこ(丸括弧・パーレン)を
- 処理と返り値が等しい場合、処理部分を囲むかっこ(波括弧・ブレース)を
省略することができます。
パラメータの初期値
function squareArea(width, height) {
if(width === undefined) {
width = 10;
}
if(height === undefined) {
height = 5;
}
return width * height;
}
const squareArea = (width = 10, height = 5) => width * height;
= 10
, = 5
部分でデフォルト値を指定できます。
逆に必須にして、エラーを投げたいときは、
const errorThrower = () => {
throw new Error();
};
const squareArea = (width = 10, height = errorThrower()) => width * height;
パラメータをオブジェクトで受け取って変数に展開
const func1 = obj => {
const a = obj.a;
const b = obj.b;
const c = obj.xxx.c;
// do something...
};
const func2 = ({a, b, xxx: {c}}) => {
// do something...
console.log(a, b, c);
};
func2({
a: "aaa!",
b: "bbb!",
xxx: {
c: "ccc!"
}
}); //> "aaa!" "bbb!" "ccc!"
標準のJavaScriptの関数の返り値から取り出したリ、
APIを叩いてデータを取得するときにも使えます。
初期値もセットできます。
返り値について返す前に処理
const func = num => {
num += 1;
return num;
};
const func1 = num => ++num;
const func2 = num => (num+=1, num);
代入演算子
代入演算子は、変数に計算結果を代入するが、
同時に、式の値としても計算結果を返す。
let num = 10;
console.log(num += 5); //> 15
console.log(num); //> 15
+=
-=
*=
/=
%=
**=
インクリメント・デクリメント、前置・後置
- 後置 なら加算/減算 前 の値を返す。
- 前置 なら加算/減算 後 の値を返す。
カンマ演算子
複数の式を評価して、最後の結果を返す。
説明は割愛したいと思う。
数値
10の累乗
一、十、百、千、万、十万、、、
1e0 === 1
1e1 === 10
1e2 === 100
1e3 === 1000
6.96e8 === 696000000
1e-10 === 0.0000000001
1e3
は $ 1×10^3 $、
6.96e8
は $ 6.96×10^8 $、
1e-10
は $ 1×10^{-10} $
文字列
1文字取り出す
const str = "abcdefg";
// 3文字目取り出す
str.substring(2, 3); //> "c"
const str = "abcdefg";
str[2]; //> "c"
オブジェクト
プロパティ名とキーが一致している
const obj = {
lorem: lorem,
ipsum: ipsum
};
const obj = {
lorem,
ipsum
};
プロパティに関数を代入する ※追記
const obj = {
name : "Alice",
greet: function() {
console.log(`I'm ${this.name}`);
}
};
const obj = {
name : "Alice",
greet() {
console.log(`I'm ${this.name}`);
}
};
配列をそれぞれの変数に代入する
const first = arr[0];
const second = arr[1];
const third = arr[2];
const [first, second, third] = arr;
プロパティをそれぞれ変数に代入する
const id = obj.id;
const name = obj.name;
const birth = obj.birth;
const {id, name, birth} = obj;
分割代入はいろいろなタイミングで使えるので、絶対に覚えておくべき。