Nullから始めるJavaScript講座 - PERFECT JavaScript on NULL

# この記事について

## この記事はJavaScriptのよく分からない言語仕様を楽しく学ぶためのものです

- ある種の縛りコーディングみたいなものです
- ネタなのであまり真剣に扱わないでください(重要)
- 主に、nullだけを使ってJavaScriptでHello, Worldを実現することを目的に講座を進めていきます
- 特に解説とか興味ない方は、一番下のHello, Worldのコードからご覧ください

![Google.png](https://qiita-image-store.s3.amazonaws.com/0/97367/7ae6b955-a3b8-a20f-14c7-193a62e61a06.png)

## ルール

この講座で紹介するコードは以下のルールを守ってコーディングされています

- null及び演算子のみで構成されていること
- null以外のリテラル表現(数値、文字列、真偽値、オブジェクト、配列、関数etc)の使用禁止

# Lesson1 - 数値を手に入れよう

まずは最も基本的な値である数値をnullから手に入れてみましょう
数値を手に入れる方法はいくつかありますが、例えば

```js
+null // => 0
```

もしくは、

```js
+!null // => 1
```

といった方法が存在します

## 解説

Lesson1のポイントは**単項+演算子**と**論理否定演算子**です
特に単項+演算子の挙動は不可解でハマりやすいので気を付けましょう
以下にいくつか例を示しておきます

```js
+"5"      // => 5
+"-5"     // => -5
+"123asd" // => NaN
+""       // => 0
+true     // => 1
+false    // => 0
+[]       // => 0
+[12]     // => 12
+[12, 18] // => NaN
+{}       // => NaN
```

# Lesson2 - 文字列を手に入れよう

次はnullから文字列を手に入れましょう
この場合には、typeof演算子を使うことができます

```js
typeof null // => "object"
```

また任意の文字を手に入れたい場合は、```String.fromCharCode()```を使いましょう
(```String.fromCharCode()```は文字コードから文字列を生成するための関数です)
まず、```String```コンストラクタは以下の方法で手に入れることが可能です

```js
(typeof null).constructor // => function String() { [native code] }
```

よって、```A```を手に入れるコードは以下のようになります

```js
(typeof null).constructor.fromCharCode(
  ((typeof !null).length + +!null) * ((typeof !null).length + +!null) + +!null
)
// => "A"
```

## 補足

Lesson1では単項+演算子を用いた数値の入手方法を紹介しましたが、文字列のlengthプロパティを利用することでさらに柔軟に数値を手に入れることが可能になります

```js
(typeof null).length // => 6
(typeof !null).length // => 7
```

# Lesson3 - 関数を手に入れよう

次は、nullから関数を手に入れましょう
nullから関数を生成するのには```Function```コンストラクタを利用します
まず、nullから```Function```コンストラクタを手に入れましょう
以下のようにして手に入れることが可能です

```js
(!null).constructor.constructor
```

ここで少し解説
```!null```は```true```なので、```(!null).constructor```は```Boolean```コンストラクタ
```Boolean```コンストラクタ自体は関数なので、```(!null).constructor.constructor```は```Function```コンストラクタを指します

よって、以下のようにして無名関数を生成できます

```js
new (!null).constructor.constructor()
// => function anonymous() {}
```

さらに、```Function```コンストラクタは第一引数に関数の中に記述する処理を文字列として渡すことができます
例えば、こんな感じ

```js
new Function("return null")()
// => null
```

これを利用して次項ではいよいよHello, Worldを実現していきたいと思います

# nullからHello, Worldしよう!!

Lesson1, 2, 3の内容を総動員するとHello, Worldのコードは以下のようになります
実際にデベロッパーツールのコンソールなどで実行して、挙動を確かめてみましょう

```js
new (!null).constructor.constructor(
  (typeof null).constructor.fromCharCode(
    (typeof !null).length * (typeof !null).length + (typeof !null).length * (typeof !null).length - (+!+null),
    (typeof null).length * (typeof null).length * (+!+null + +!+ null + +!+null),
    (typeof null).length * (typeof null).length * (+!+null + +!+ null + +!+null) - (typeof !null).length,
    (typeof null).length * (typeof null).length * (+!+null + +!+ null + +!+null) + (typeof !null).length - (+!+null),
    (typeof null).length * (typeof null).length * (+!+null + +!+ null + +!+null) + (typeof !null).length + (+!+null),
    (typeof null).length * (typeof !null).length - (+!+null) - (+!+null),
    (typeof null).length * (typeof !null).length - (+!+null) - (+!+null) - (+!+null),
    (typeof null).length * (typeof null).length * (+!+null + +!+null),
    (typeof null).length * (typeof null).length * (+!+null + +!+ null + +!+null) - (typeof !null).length,
    (typeof null).length * (typeof null).length * (+!+null + +!+ null + +!+null),
    (typeof null).length * (typeof null).length * (+!+null + +!+ null + +!+null),
    (typeof null).length * (typeof null).length * (+!+null + +!+ null + +!+null) + (+!+null + +!+null +!+null),
    (typeof null).length * (typeof !null).length + (+!+null) + (+!+null),
    ((typeof null).length - +!+null - +!+null) * ((typeof !null).length + +!+null),
    (typeof null).length * (typeof !null).length * ((+!+null) + (+!+null)) + +!+null + +!+null + +!+null,
    (typeof null).length * (typeof null).length * (+!+null + +!+ null + +!+null) + (+!+null + +!+null +!+null),
    (typeof null).length * (typeof null).length * (+!+null + +!+ null + +!+null) + (typeof !null).length - (+!+null),
    (typeof null).length * (typeof null).length * (+!+null + +!+ null + +!+null),
    (typeof !null).length * (typeof !null).length + (typeof !null).length * (typeof !null).length + (+!+null) + (+!+null),
    (typeof null).length * (typeof !null).length - (+!+null) - (+!+null) - (+!+null),
    (typeof null).length * (typeof !null).length - (+!+null)
  )
)()
```

もう少し最適化できる部分もありますが、とりあえずこんな感じでnullでHello, Worldできますよ、ということでした
(誰得なんだこの記事)

ちなみにこれ、他の言語でもやってみると面白いかも
Rubyのnilとか