LoginSignup
17
13

More than 5 years have passed since last update.

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

Posted at

この記事について

この記事は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とか

17
13
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
13