4
2

More than 3 years have passed since last update.

IE11でも動くワンライナー湯婆婆を作り、IE11対応のつらさを再認識する

Last updated at Posted at 2020-11-17

何番煎じかわからないネタをやります。

Q.なぜこんなことを?

流行りの湯婆婆にのっかりたかったんです。

Q.JSはみんなやってるよね?

はい、しかもすげーLTGMも稼いでるのでもう勝てないなって。
なのでIE11でも動くのをやってみようと思いました。

Q.IE11って需要あるの?

未だにIE対応が必要だと言われることがあるので、あと数年は需要があるかもしれない。
でも個人的には早く滅びてほしいと思っていますね(笑)

というわけでコード

JSのコード自体はワンライナーの体を保っている・・・はず。

湯婆婆.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>湯婆場</title>
    <script>
    (function(f){alert((function(f,n){return "フン。"+f+"というのかい。贅沢な名だねぇ。今からお前の名前は"+n+"だ。いいかい、"+n+"だよ。分かったら返事をするんだ、"+n+"!!"})(f,f[Date.now()%f.length]))})(window.prompt("契約書だよ。そこに名前を書きな。",""))
    </script>
</head>
</html>

ポイント

まず、一行で書いてしまったJSコードを一旦整形しましょう。

(function (f) { 
  alert(
    (function (f, n) { 
       return "フン。" + f + "というのかい。贅沢な名だねぇ。今からお前の名前は"
              + n + "だ。いいかい、" + n + "だよ。分かったら返事をするんだ、" + n + "!!" 
    })(f, f[Date.now() % f.length])
  )
})(window.prompt("契約書だよ。そこに名前を書きな。", ""))

真面目な書き方をするとこうなる

ワンライナーにするためにクソコードにしてしまった。
そしてこっちのほうが文字数が少ないとかいう問題にも目をつむってほしい。

// プロンプトで文字入力
const f = window.prompt("契約書だよ。そこに名前を書きな。", "");
// 時間使って疑似ランダム
const n = f[Date.now() % f.length];
// 結果表示
alert("フン。" + f + "というのかい。贅沢な名だねぇ。今からお前の名前は"
              + n + "だ。いいかい、" + n + "だよ。分かったら返事をするんだ、" + n + "!!" );

関数を作ってそれを即時実行

JSの関数を作って実行する場合には、だいたい以下のようにします。

function multiple(n) {
  return n * n;
}
const nn = multiple(8);

それを、以下のように書くことで即時に実行することができます。

const nn = (function(n) {
  return n * n;
})(8);

// ES2015だとここまで短縮はできる
const nn = ((n)=>n*n))(n);

正直、普通に書いたらいいじゃん、と思うでしょう。
本来はjQueryプラグインなんかを作るために多用していたテクニックです。

(function($){
  $.fn.myPlugin = function() {
    // ここにプラグインの中身を記載
  }
})(jQuyery);

こうすることで、window.onloadよりも前のタイミングでjQueryプラグインのロードを済ませつつ、
カプセル化を(一応)実現できるようになるのです。

要はclass構文がなかった頃のレガシーコードなので、使ってドヤらないように注意しましょう。

IE11では使えないJSの機能たち

JavaScriptにはES2015という規格があり、いろいろと新機能が追加されました。
しかしながら、IE11は中途半端に対応しているため動かない書き方が多数存在します。

アロー関数

アロー関数とは、関数定義を簡略化して記載するための記法です。
簡易的な計算を記載したり、コールバック関数としての記載をする場合によく使用します。

function(n) {
  return n * n;
}
// 下のように書ける
(n) => n * n;

なお、厳密にはthisの扱いが変わったりしますので、
なんでもかんでもアロー関数にしたらいいというわけではないので注意してください。

テンプレート文字列

テンプレート文字列は、CやJavaでのString.formatに相当する機能で、
文字列の中に変数を定義してテンプレートとして定義できます。

const name = "太郎";

let message = "こんにちは、" + name + "さん";

// これを以下のように書ける
let message = `こんにちは、${name}さん`;

ちなみに、アロー関数とテンプレート文字列を使うだけでも、ここまですっきりします。
(え、すっきりしない?)

((f) => alert(((f,n)=>`フン。${f}というのかい。贅沢な名だねぇ。今からお前の名前は${n}だ。いいかい、${n}だよ。分かったら返事をするんだ、${n}!!`)(f,f[Date.now()%f.length])))(window.prompt("契約書だよ。そこに名前を書きな。",""))

さいごに

短さや可読性は先人の方のほうが上ですので、真面目にJSの勉強をしたい方はそちらを参照しましょう。

IE11の対応を予定していない皆様はこの記事は幻のエンディングだと思って忘れるとよいでしょう。

PS追記

こんなんあったんか・・・
先走ってしまったので皆さんはきをつけてね。
https://qiita.com/advent-calendar/2020/yubaba

4
2
0

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
4
2