ワンライナー化
処理;処理;
一文で表現できる処理はカッコとカンマを使って一文にまとめることができる
forやbreakなどの処理を使っている場合はmap等のメソッドに置き換えるか諦める必要がある
let x=2;
x=x*x;
x=8-x;
console.log(x);
// ↓↓↓
let x=2;
(x*=x,console.log(x=8-x));
jsは実行する関数と渡そうとしている引数の数が合わない場合でも実行される
関数の受け取る引数が多いとundefinedが入るのでデフォルト引数を使って追加の変数の宣言ができる
関数に渡す引数が多いとカッコをとカンマを使ったワンライナー化とほぼ同じだが引数は渡される状態になる
let
前述の(,,)の中では変数の宣言ができない
しかし即時関数を利用すれば変数の宣言が可能である
実行時に引数の受け渡しが難しい(mapの中など)場合は引数が渡されない範囲でデフォルト引数を利用すれば同様のことが可能である
let x=2;
(x*=x,console.log(x=8-x));
// ↓↓↓
(x=>(x*=x,console.log(x=8-x)))(2);
//or
((x=2)=>(x*=x,console.log(x=8-x)))();
if文
jsの論理演算子は先に全て実行してから評価では無く実行と評価を繰り返すので置き換えが可能である
elseも用いる場合は三項演算子が良い
if(true)say(nyan);
// ↓↓↓
true&&say(nyan);
if(!true)say(nyan);
// ↓↓↓
true||say(nyan);
if(true)say(nyan);else say(nya);
// ↓↓↓
true?say(nyan):say(nya);
// ↓↓↓
say(true?nyan:nya);
配列を操作するループ
.reduce()でほとんどのループは置換できる
ちなみにmapやeachなど配列のメソッドはいろいろあるが全てreduceで表現できる
複数のループ系メソッドを繋げている場合はほとんどの場合reduce一本にまとめられるのでよく考える
if(x)break;fx();はx||fx();に置き換える
breakがないプログラムの方が実行速度は劣るが読みやすい(と思っている)
シェーダーを書いていた人間なので各ループの中の実行時間は近いほうが望ましいと思っているが実際どうなの?
let arr=[1,2,3,4,5],
result=0;
for(let i=0;i<arr.length;i++)result+=arr[i];
// ↓↓↓
let arr=[1,2,3,4,5],
result=arr.reduce((a,x,i)=>a+x,0);
initial valueをObjectにすることで複数の値を格納できて便利
特定の回数回したいループの場合は長さのある空配列を用いると良い
[...Array(3)]
// >>[undefined,undefined,undefined]
オブジェクトを操作するループ
Object.entries()を使って配列に変換して操作する
操作が終わったらObject.fromEntries()でオブジェクトに戻す
Object.fromEntries(arr)はarr.reduce((a,x)=>(a[x[0]]=x[1],a),{})の方が速い
そもそもfromEntriesしたい場面においてentriesな配列に変換してから投げることが多いのでそれをするならreduceした方が良い
switch文
switch(x){
case 'a':console.log('aだね');break;
case 'b':console.log('bだね');break;
case 'c':console.log('cだね');break;
default:console.log('あ〜あ お前のせいです')break;
}
// ↓↓↓
({
a:()=>console.log('aだね'),
b:()=>console.log('bだね'),
c:()=>console.log('cだね')
}[x]||(()=>console.log('あ〜あ お前のせいです')))();
オブジェクトは三項演算子とスプレッド演算子を使って一部の要素のみ切り替えることも可能なのでswitchよりも強力
その他
Math.floor
正確にはfloorではなくてtrunc
ビットor演算は数を整数に変換する
Math.trunc(x);
// ↓↓↓
x|0
実行速度に関しては
ビットorは32bit整数への変換が挟まるのでMath.truncよりも遅いと思われる
x==-1
正確にはx|0==-1
ビットnot演算子は-1のときに0を返すのでこれを利用する
indexOf()が-1を返したときの検出などに便利
(x==-1)==!~x;
undefined
voidが常にundefinedを返すことを利用
undefined===void 0
booleanな配列
bool型の入った短い(length<32)配列はビット演算子を使った使ったものに置き換えられる
変数名のつけ方???
人力minifyしまくると変数名というより引数名になる点はさておき
forEach,map,filter等(各要素,添字,元配列)な引数は外側から
(x,i)
(y,j)
(z,k)
の順で使う
このペアはずらして使うべきではない
reduceの場合は(a,x,i),(b,y,j)とか
reduceの中でreduceしたい場面が発生することはあまりない
元配列についてはほとんど使う場面がない
使いたい状況が発生している時点で使っているメソッドが適していない可能性がある
使うとすれば全体の長さの把握程度であってその場合は
(x,i,{length:l})
x,y,z,i,j,kは引数用にとっておきたいので
一番外側の関数の引数など大本になるオブジェクトを入れる場合はwを使う
グローバルに置きたくない場合はさらにオブジェクトでくるんであげるといいかも
個人的にはdとかqとかをよく使う