JavaScriptのminify（最小化・圧縮）の解説をいくつかまとめてみた

JavaScriptを手で書いたあと、Webで公開する際にはminifyすることが定番、のはず。
けれども、minifyしたあとのJavaScriptは元と全く同じ動作をするが、文法すら全く異なるように最小化されることが多い。

JavaScript初心者のわたしとしては`🤔🤔？？？`となることが多かったので、言語仕様を勉強するためにもいくつかまとめてみた。

#例1：ローカル変数の置き換え
```javascript:minify前
(function (position) {
	const SOURCE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
	return SOURCE[position];
})(3);
```

```javascript:minify後
(function(a){const b="ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";return b[a]})(3);
```

##解説
JavaScriptのスコープには、「グローバルスコープ」と「ローカルスコープ（関数スコープとブロックスコープ）」があり、グローバルスコープを汚さないために[即時関数](https://qiita.com/katsukii/items/cfe9fd968ba0db603b1e)を利用することがある。
当然、即時関数内の変数名は自由に設定できるので、aとかbとか1文字で適当に置き換える。

#例2：trueとfalseの置き換え

```javascript:minify前
let a = true;
let b = false;
if(c===true){
    //（略）
```

```javascript:minify後
let a=!0,b=!1;if(!0===c){//（略）
```
##解説
`a = true`とするよりも`!0`（0の反対、論理否定演算子）としたほうが短い。`true`は4文字だけど`!0`は2文字で済む。

なお、JavaScriptにおいて、`true`と`!false`と`!0`は完全に厳密に同値です。同様に、`false`と`!true`と`!1`も。
（なぜこうなるか理由がわからなかったので詳しい方コメント下さい…）

```javascript:
console.log(true===!false);//true
console.log(!false===!0);//true
console.log(!0===true);//true
console.log(false===!true);//true
console.log(!true===!1);//true
console.log(!1===false);//true
```
ちなみにJavaScriptで`false`と評価されるのは`false`、`''`（空文字）、`NaN`、`0`、`-0`、`undefined`、`null`の7つらしい

###ちなみに
↑のスクリプトでminifyされたあと、`!0===c`と[ヨーダ記法](https://ja.wikipedia.org/wiki/%E3%83%A8%E3%83%BC%E3%83%80%E8%A8%98%E6%B3%95)（==などの比較演算子の左側にリテラルを書くこと）になっているが理由は謎。

#例3：論理演算子&&と||の活用
```javascript:minify前
var root;
if (typeof self == 'object' && self.self === self) {
    root = self;
} else if (typeof global == 'object' && global.global === global) {
    root = global;
} else {
    root = this;
}
```

```javascript:ちょっとminify後
var root = typeof self == 'object' && self.self === self && self ||
            typeof global == 'object' && global.global === global && global ||
            this;
```
[参考](https://qiita.com/Imamotty/items/bc659569239379dded55)より引っ張ってきました。

JavaScriptの仕様として、[引用元](https://ja.javascript.info/logical-operators)
>OR "||" 演算子は次のように動きます:
>1.左から右にオペランドを評価します。
>2.それぞれのオペランドで、それを Boolean に変換します。もしも結果が true であれば、停止しオペランドの本来の値を返します。
>3.もしもすべての他のオペランドが評価された場合(i.e. すべて 偽 のとき), 最後のオペランドを返します。


>AND "&&" 演算子は次のように動きます:
>1.左から右にオペランドを評価します。
>2.それぞれのオペランドで、それを Boolean に変換します。もしも結果が false の場合、ストップしそのオペランドの本来の値を返します。
>3.もしもすべての他のオペランドが評価された場合(i.e. すべて 真 のとき), 最後のオペランドを返します。

というのがあります。

## 個人的にこう理解した
### OR
要するに、`||`は左から順にみていって最初に`true`になるものを返すということです。
`◯ || △ || □`のようなとき、`||`は1つでも`true`になれば全体として`true`になりますね。
なので、左から順にみていって、1つでも`true`なものが見つかればそいつを返します。
### AND
一方、`&&`は左から順にみていって最初に`false`になるものを返す、ということです。
`◯ && △ && □`のようなとき、`&&`は1つでも`false`になれば全体として`false`になりますね。
なので、左から順にみていって、1つでも`false`なものが見つかればそいつを返します。

##ANDとORの優先順位
また、`&&`演算子の方が`||`より優先順位が高いです。
これを思いっきり利用したのが↑のスクリプトです。

###例
&&の方が優先順位が高いので、例えば

```javascript:
'ぴえん🥺' && 'ぱおん🥺' || 0 && 1 && 2
```


は`"ぱおん🥺"`が返ります。

まず`'ぴえん🥺' && 'ぱおん🥺'`を評価して`"ぱおん🥺"`が返り、次に`0 && 1 && 2`を評価して`0`が返り、最後に`"ぱおん🥺" || 0`を評価して`"ぱおん🥺"`が返るイメージです。

#例4：カンマ演算子
```javascript:minify前
let a=function(event){
    event.preventDefault();
    event.hogehoge();
    return event.result;
}
```

```javascript:minify後
let a=function(e){return e.preventDefault(),e.hogehoge(),e.result};
```

いい例が見つからんかった…

JavaScriptの`,`は演算子で、それぞれの中身を左から右に順番に評価し、最後の式の値を返します。

minifyされたJSファイルのいたるところで`,`は使われますが、結局のところ`左から右に順番に評価し、最後の式の値を返す`を理解していれば解読できます。



# 最後に
`magnify`（大きくする）という英単語があるんだから、`minify`は当然「小さくする」って意味だろう

と思って非プログラマーの英語の先生に`minify`と言ってみたら、「何いってんだお前」と言われました。

minifyは英語の辞書には載ってません。プログラマーにのみ通じる単語です🙄

大きくするって単語は`magnify`とか`enlarge`って単語があるのに、小さくするのは`make ◯◯ smaller`しかないのなんで？


# 最後に2
わたしJavaScript初心者なので間違いあったらごめんなさい🥺