Posted at

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

More than 3 years have passed since last update.


この記事について


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


  • ある種の縛りコーディングみたいなものです

  • ネタなのであまり真剣に扱わないでください(重要)

  • 主に、nullだけを使ってJavaScriptでHello, Worldを実現することを目的に講座を進めていきます

  • 特に解説とか興味ない方は、一番下のHello, Worldのコードからご覧ください

Google.png


ルール

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


  • null及び演算子のみで構成されていること

  • null以外のリテラル表現(数値、文字列、真偽値、オブジェクト、配列、関数etc)の使用禁止


Lesson1 - 数値を手に入れよう

まずは最も基本的な値である数値をnullから手に入れてみましょう

数値を手に入れる方法はいくつかありますが、例えば

+null // => 0

もしくは、

+!null // => 1

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


解説

Lesson1のポイントは単項+演算子論理否定演算子です

特に単項+演算子の挙動は不可解でハマりやすいので気を付けましょう

以下にいくつか例を示しておきます

+"5"      // => 5

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


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

次はnullから文字列を手に入れましょう

この場合には、typeof演算子を使うことができます

typeof null // => "object"

また任意の文字を手に入れたい場合は、String.fromCharCode()を使いましょう

(String.fromCharCode()は文字コードから文字列を生成するための関数です)

まず、Stringコンストラクタは以下の方法で手に入れることが可能です

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

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

(typeof null).constructor.fromCharCode(

((typeof !null).length + +!null) * ((typeof !null).length + +!null) + +!null
)
// => "A"


補足

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

(typeof null).length // => 6

(typeof !null).length // => 7


Lesson3 - 関数を手に入れよう

次は、nullから関数を手に入れましょう

nullから関数を生成するのにはFunctionコンストラクタを利用します

まず、nullからFunctionコンストラクタを手に入れましょう

以下のようにして手に入れることが可能です

(!null).constructor.constructor

ここで少し解説

!nulltrueなので、(!null).constructorBooleanコンストラクタ

Booleanコンストラクタ自体は関数なので、(!null).constructor.constructorFunctionコンストラクタを指します

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

new (!null).constructor.constructor()

// => function anonymous() {}

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

例えば、こんな感じ

new Function("return null")()

// => null

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


nullからHello, Worldしよう!!

Lesson1, 2, 3の内容を総動員するとHello, Worldのコードは以下のようになります

実際にデベロッパーツールのコンソールなどで実行して、挙動を確かめてみましょう

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とか