僕は舐めていた。JavaScriptの力を、そして社会人の出会いの少なさを。
僕の名前は鈴木順。何の変哲も無い名前なので、みんなからは頭文字を取りJS(Jun Suzuki)と呼ばれている。
どこにでもいる27歳、今年で社会人歴=彼女いない歴5年目となる。
世間は春を迎えるというのに、僕に人生の春が訪れる気配はない。
というか、つい春を恋の芽吹きに例えてしまったが、夏の太陽のような熱い恋でも、
秋の落葉の如く切ない恋でも、冬の暖炉のように温もり溢れる恋でも、なんでもいいのだ。
年がら年中、僕は彼女が欲しい。
そんな時、会社の同僚が昨今流行しているマッチングアプリの「Tinder」で彼女を作ったという話を聞いた。
聞けば、アプリから推奨される女の子の写真とプロフィールを見て会いたいと思えば「Like」、思わなければ「Unlike」を押し、
向こうの子も僕に会いたいと思ってくれたらメッセージがやり取りできるのだという。
思えば高校時代、僕のhotmailに送られてきた「綺麗な人妻とデートするだけでお小遣いGet」という
ホットなメールに唆されて電話番号を登録したことがあった。
その瞬間時を重ねて、怖いオジサンから銀行振込要求の鳴り止まない電話が来て以来、トラウマとなっていた出会い系サイト。
10年来のトラウマを乗り越え、男の戦いに挑む時が来たらしい。
早速登録したTinder。サイト上で女の子がわんさか出てきてよりどりみどりだが、僕だって誰でもいいわけじゃない。
最低限の条件を、僕はJavaScriptで以下のように定義した。
const photo = document.querySelector('img'); const age = document.getElementById('age'); const ageText = age.textContent; const prof = document.getElementById('profile'); const profText = prof.textContent; const like = document.getElementById('Like'); const unlike = document.getElementById('Unlike');
まず、アプリ内の各要素を定数へ代入していく。
JavaScriptとHTMLを組み合わせて何かをしようと思うなら、関係するHTML内の要素を指定して、
わかりやすい名前を付けた定数に入れてあげたほうが後々見やすいコードになるのだ。
if ( photo === '美人' ) { //photoが美人だったら click(like); //Likeをclick } else { //さもなくば click(unlike); //Unlikeをclick }
if文を使うと、条件分岐ができる。僕の場合、美人しかLikeは押したくないし、そうでなければUnlikeしたい。
そのときには、if に続く( ) の中に条件を書いてあげて、もしその条件に合致した場合の結果を { } の中に書いてあげればいい。
そうそう、このときの「等しい」は === と表す点にご注意あれ。
しかし、ここには問題がある。世紀の極悪アプリ・Snowを使うと、
IKKOばりの美白&デカ目魔改造が施されるため、皆が皆美人に見えてくるのだ。
そこで僕は、以下のように条件を変更した。
if ( photo === '美人' && photo !== 'snowで撮影' ) { //photoが美人かつsnowではなかったら click(like); //Likeをclick } else { //さもなくば click(unlike); //Unlikeをclick }
複数条件は && で繋げられ、「等しくない」は !== で表すことができる。
しかし、そもそもいわゆる美人顔ではなくとも、僕は個人的に元レスリング選手の浜口京子の顔が好きだ。
すると、文章は以下のようになる。
if ( photo === '美人' && photo !== 'snowで撮影' ) { click(like); } else if ( photo === '浜口京子' ){ //そうじゃなくても、photoが京子だったら click(like); //Likeをclick } else { //さもなくば click(unlike); //Unlikeをclick }
else if を使えば、複数条件による分岐も書くことができるのだ。
しかし、何やら文が長くなってきた。それでも、僕のおこだわりポイントは尽きることがない。
そこで、論理演算子と条件演算子を用いて文を短くしながら最終条件を決めた。
( photo === '美人' && photo !== 'snowで撮影' && ageText < 36 && profText.includes('社交的') || photo === '浜口京子' ) ? click(like) : click(unlike);
美人でSnowで撮影してなくて36歳未満で社交的なプロフを書いているか、
京子(京子はいくつになっても綺麗だ)じゃないとLikeを押さないというかなり厳しい条件を設定してしまった。
これで、本当に彼女が見つかるのかなあ…。
3ヶ月後、僕は浜松町にある「焼肉くにもと」のテーブルでそわそわしていた。
今日は33歳のキレイめな看護師・Ayax さんと初めて会う約束を取り付けていたのだ。
消化器科に勤めるAyaxさんから「美味しいレバーを焼きたい」と言われた時には(文字通り)肝を抜かれたが、
持ち前のITリテラシーの高さと食べログプレミアム検索を駆使して、この店を予約したのだった。
二人前12,000円分の肉は既に予約済、ふところも今晩は暖かくしてあるので準備万端だ。期待ageである。
しかしまあ、随分とAyaxさんの到着が遅れている。
…その時、Ayax さんから「ごめん、今日やっぱり風邪っぽいわ(泣き笑いの顔文字)」というLINEが入った。
やれやれ、もうこれでTinderで知り合った子に当日風邪を引かれるのは3回目となる。
次からは、if( photo === '健康そう' ) という条件文も加えておかなければいけないな…。
涙の塩味をアクセントに、二人前のレバーを噛みしめた僕はやがて、東京の中心でアイを叫んだけものとなった。
「戦を見て矢を矧(は)ぐ」とは、戦いが始まってから矢を作るという準備を怠る愚かさを例えたことわざだ。
無論、合コンという現代の戦場にあってもなお、活きる言葉といえよう。
僕の名前は鈴木順。何の変哲も無い名前なので、みんなからは頭文字を取りJS(Jun Suzuki)と呼ばれている。
Tinderで連戦連敗を積み重ねた僕は、三十六計逃げるに如かずとばかりに、転戦することとした。
同僚に頼み込み、合コンをセッティングしてもらったのだ。
高度な情報社会において、事前の情報整理が大きな武器となることは、諸君も知っておいて損は無いだろう。
早速、僕は下調べに動き出した。
const females = Facebook.getElementsByClassName('今日来る女の子たち'); //今日来る女の子たちのFaceBookプロフィールを females.forEach(item => { //それぞれ let myBrain = document.getElementById('僕の脳みそ'); myBrain += item.textContent; //僕の脳みそに女の子の情報を叩き込む });
getElementsByClassNameでは、要素ではなくてHTMLCollectionが指定されるので、つまり要素がたくさんごそっと代入されてしまう。
こういったときには、forEachによって各itemを操作する手段が有効だ。
僕はこうして全ての女の子のSNSから、容姿、趣味、嗜好といったあらゆる情報を脳に叩き込んだ。
会話は大盛り上がりに違いない、僕は心の中でほくそ笑んでいた。
合コンの開始は週末の夜8時。少し遅れてきた女の子たちの到着に合わせ、早速の乾杯。
少し涼やかになった夏の夜、冷えたビールにノースリーブの女の子。まさに至福の瞬間ではなかろうか。
しかし、だ。事前準備の甲斐なく、いざ女の子を目の前にすると、ぎこちなくなってしまう自分がいた。
特に、今対峙しているのは、事前に目星を付けていた本命ののどかちゃん。
写真より実物はもっと綺麗で、キューティクルが天使の輪となっている神々しさを前に、僕は一人空回りを続けていた。
そもそも一言目から「シュウウエムラがお好きなんですか?僕も好きです←」などとぶっこんだのがいけなかった。
シュウウエムラは、20代女性に人気のデパコス(デパートで販売されるコスメ)のブランド。
最近の彼女のInstagramにシュウウエムラの化粧品が上げられていたため水を向けたのだが、
そもそもあまり男性が使うブランドではない。かといって、事前リサーチでこのブランドを知ったとは口が割けても言えない。
彼女の微妙な反応に、さらなる空回りを続けてしまう僕。
ええいままよ、こんな時こそ、アルコールの力を借りる時だ!
僕は会話に自信がつくまで、以下の要領で酒を煽り続けた。
let のどかちゃんからの好感度 = 0; const 胃袋 = []; for( let 自信 = 0; 自信 < 緊張; 自信++ ) { //自信が緊張を上回るまで、以下の命令を実行し続ける 飲み干すジョッキ++; //ジョッキを追加 胃袋.push('酒'); //胃袋に酒を追加 のどかちゃんの好感度 = 胃袋.length; //胃袋の酒の量だけ好感度が上がる };
for文を使えば、上記のように簡単にループ文(命令を繰り返し実行する文)を書くことができる。
次第に、思惑通りお酒の力によって話が饒舌に進むようになってきた。
心なしか、最初はこわばっていたのどかちゃんの顔もほころんで、好感度はぐいぐい上がっているようだ。
ちょっとしたスキンシップも生まれてきて、なんだか今日はいけそうな気がする…!
…しかし、この時僕は、この命令は本当はif文の条件分岐がネストされていることに気づいていなかった。
let のどかちゃんからの好感度 = 0; const 胃袋 = []; for( let 自信 = 0; 自信 < 緊張; 自信++ ) { //自信が緊張を上回るまで、以下の命令を実行し続ける 飲み干すジョッキ++; //ジョッキを追加 胃袋.push('酒'); //胃袋に酒を追加 if ( 飲み干すジョッキ > 9 ) { 胃袋 = null; のどかちゃんの好感度 = null; break; } のどかちゃんの好感度 = 胃袋.length; //胃袋の酒の量だけ好感度が上がる };
胃袋という名の配列へ無理やりpushを続けていた酒はやがて10杯目ともなると、 無残にもテーブルの上へ胃液と混じってヌルヌルとすべて流れ出ていった。 目前には、ゴミムシをちらりと見やるような女性陣の冷たい目つき。 努力空しく、のどかちゃんからの好感度はもはや無と化してしまったのだった。
女心と秋の空…全く、うまい事を云う奴も居たものである。
そして深く憂いを帯びていく紅葉の如く、僕の心は沈み込んでいた。
僕の名前は鈴木順。何の変哲も無い名前なので、みんなからは頭文字を取りJS(Jun Suzuki)と呼ばれている。
合コンで知り合ったのどかちゃんを、嘔吐の悲劇から逆転劇でなんとか手籠めにした僕。
その幸せも束の間、些細な出来事から、またもやのどかちゃんに怒られ、そっぽを向かれてしまったのだった。
しかしまあ、怒り心頭になった状態の女性の理不尽さたるや、村田修一の巨人退団並みである。
あまり頻繁に謝りを入れれば、「軽薄すぎ。本当に反省しているの?」と返ってくるし、かといって
ほとぼりが冷めるまでほっとこうとすれば「何かかける言葉とかないの?」とくる。ああ言えば上祐、どうしようもない。
無論、のどかちゃんのことは好きだ。そんなちょっとわがまま気質なところも含めて好きだ。
配列に代入するならば、
nodoka_no_kawaii_points = ['ふにふにのおなか', 'いやしのえがお', 'なめらかなかみ', 'ねこのようなきまぐれ']
ということになるだろうか。
でも、今回は実に厄介だ。デバッグを慎重に行わなければ、コードは二度と動かなくなる可能性がある。
のどかちゃんの機嫌を取り戻すべく、僕はラインでのやり取りを自動化するJavaScriptを手掛け始めた。
const mailing = () => { const textarea = document.getElementById('テキスト入力フォーム'); textarea.value = 'ごめんね…'; //テキスト入力フォームにvalueを代入 document.querySelector('送信ボタン').click(); //送信ボタンをクリック setTimeout(mailing, 10800000); //3時間後 }; mailing();//上記の命令を再帰処理
setTimeoutを使えば、一定時間を置いて実行する命令を書くことができる。
この場合は、10,800,000ミリ秒=3時間後にメッセージが送付できる。
さらに、再帰処理の形を取れば、上記命令が繰り返されるので、3時間おきにメッセージ送付が実行される。
うっとうしすぎず、ほったらかしすぎず。我ながら非常に良い間合いである。
…しかし、高収入求人バニラの宣伝トラックでもあるまいし、ひたすら「ごめんね…」と
連呼しているようではさすがに相手の心に刺さらないだろう。
ここは、いくつかの送付文候補の中からランダマイズがかかるようにしておこう。
const mailing = () => { const textarea = document.getElementById('テキスト入力フォーム'); const number = Math.floor(Math.random() * 5); //ランダムに0~4の値を出す switch (number) { case 0: //numberが0のときの処理 textarea.value = 'ごめんね…素直じゃなくて'; break; case 1: //numberが1のときの処理 textarea.value = '今すぐ会いたいよ…'; break; case 2: //numberが2のときの処理 textarea.value = '電話もできない、どうしよう…'; break; case 3: //numberが3のときの処理 textarea.value = '月の光に導かれ、何度も巡り合う…'; break; case 4: //numberが4のときの処理 textarea.value = 'ミラクル・ロマンス…'; break; } document.querySelector('送信ボタン').click(); setTimeout(mailing, 10800000); //3時間後に実行 }; mailing();//上記の命令を再帰処理
Math.random() で0.000...~1.000...のランダムな数を作成し、これを5倍。
さらにMath.floor()で切り捨てすると、0~4の値がランダムに作成される。
また、条件分岐はif文でも書けるが、時にcase文の方がもっと見やすくなることがある。
配列を使えばもっとスマートになるので、気になった貴方は是非挑戦あれ。
こうして僕は敬愛する美少女戦士セーラームーンの主題歌「ムーンライト伝説」から
インスピレーションを得て、5文を仕上げた。
僕はさながら月野うさぎ、のどかちゃんは僕のタキシード仮面様。
平成初期生まれののどかちゃんであれば、世代的に間違いなく刺さる。
これで準備は万端、コードに付きっ切りなあまり、気づけば空も白んできてしまった。
仲直りをコードに任せてようやく安心した僕は、やがて深い眠りについたのだった。
久々にストレスから解放されたせいか、ぐっすりと寝てしまい、起きるころには昼過ぎとなっていた。
俄然、気になるのは修復されているであろうのどかちゃんとの仲である。早速ラインの画面を開いてみた。
なんと、ランダムに送るはずのメッセージは4回ともよりによって「ミラクル・ロマンス」の決め台詞を引いてしまっていた。
これは確率にして、256times繰り返してようやく1度巡り合うミラクルである。
しかも、肝心の反応は「は?」の一言。
思惑は外れ、全然刺さっていない、というか火に油を注いだ感すらある。
setTimeoutのような時任せでは、解決できない問題もあるってことか…。
ようやく腹を決め、息を大きく吸いながら携帯を天高く掲げた27歳の月野うさぎこと僕は、
「ムーン・プリズム・パワー・メーキャップ!」の掛け声と共に音声通話ボタンを押した。
人はみな孤独の中、あの鐘を鳴らすのは僕だ。
僕の名前は鈴木順。何の変哲も無い名前なので、みんなからは頭文字を取りJS(Jun Suzuki)と呼ばれている。季節はめぐり、師走となった。
猫も杓子もクリスマスとやらに浮つく季節にあって、例年の僕は孤独を「飲む福祉」ことストロングゼロで飲み下し、
静かにTBSラジオの爆笑問題カーボーイを聴いているのがオチであった。
でも、今年は違う。僕の隣にはのどかちゃんがいるのだ。
付き合い始めてはや半年。おかげで、時には喧嘩もしたけど、振り返ると半年とは思えないくらい満ち足りて、幸せな日々を過ごした。
ちょっと早いかもしれないけど、僕は既に決意を固めていた。生涯の伴侶はこの子しかいない。
人はみな悩みの中、あの鐘を鳴らすのは僕だ。
…あの鐘って、何のことかはよく分からないのだけど。
実は、今晩は彼女が普段使っている指輪をこっそりと拝借して、ぴったりのサイズの婚約指輪を用意していた。
プロポーズの場所は、最初は背伸びをした夜景の見えるレストランなども考えたが、
以前立ち読みした週刊プレイボーイに「女は自宅が一番オチる!」と書いてあったのを思い出した。
それにクリスマスの町中はごみごみしているし、舞台は我が家。決まりである。
当日は、成城石井で仕入れた普段よりちょっといいワインとツマミをあてに、
僕たちはささやかに聖夜を祝いあった。やがて、時刻は夜10時を回ろうかという頃合い。
あまり酔いが回ってしまっていると、相手の告白が真剣かわからず白けてしまうと、
週刊プレイボーイの「オンナの本音座談会」という記事にも書いてあった。
さすれば、いつ行くのか?今でしょう。
僕は生唾を飲み込み心を落ち着かせると、「今日、のどかちゃんに渡したいものがあるんだ…」と、背後からプレゼントを取り出した。
わなわなと差し出したのは、婚約指輪、そして僕の名前を書いた婚姻届である。
「のどかちゃん、僕と結婚してほしい」。僕は祈るような気持ちで、今後の展開を心にJavaScriptで記述した。
const suzuki = [鈴木順]; //鈴木家の世帯。このとき[]を用いると、値を複数入れることができる配列構造となる const answer = document.getElementById('のどかちゃんの回答'); cosnt ring = document.getElementById('婚約指輪'); const nodoka = document.getElementById('のどかちゃん'); const daikokuya = document.getElementById('質の大黒屋'); const konninTodoke = document.querySelector('婚姻届'); if(answer){//もし答えがイエスなら nodoka.appendChild(ring); //のどかちゃんの子要素に婚約指輪を追加 konninTodoke.addEventListener ('submit', () => { //更に婚姻届を提出すると nodoka.classList.add('鈴木'); //のどかちゃんのクラス名は鈴木になる suzuki.push('のどか'); //鈴木家の配列にのどかちゃんが入る }); }else{ daikokuya.appendChild(ring); //指輪は質に入れ、払い戻しの金で僕はお遍路さんになる }
プロポーズの結果は当たり前だが、trueかfalseの二者択一である。
したがって、このときanswerは真偽値となり、if文の条件分岐にそのまま用いることができる。
また、addEventListenerを用いると、イベント発火を設定することができる。
上記の場合は、婚姻届が提出されたとき、のどかちゃんの戸籍と鈴木家の謄本が大きく変わることを表している。
まさかの展開に、最初は言葉を詰まらせていたのどかちゃん。
次第に、想いは涙となって溢れ出てきていた。首を縦に振るのどかちゃん。
どうやら、指輪を質に入れる必要はなさそうだ。
彼女のtrueが、涙が、僕にとっては最高のクリスマスプレゼントだった。
「今晩は二人でcreateElementして、これからの鈴木家に新しくappendChildできるように頑張ろう。
そしたらのどかちゃんは、文字通り『ペアレントのど(ParentNode)か』になるね♡」
聖夜にふと思いついた、キレキレのJSギャグに暗黒微笑を浮かべる僕と、
理解が及ばず顔にエラーログを出力しているのどかちゃん。
僕は身体で一つ一つの意味を丁寧に教えるべく、やがてのどかちゃんを優しくベッドへ押し倒したのだった。
その晩、僕は除夜の鐘を256times強く突き、夜通し鳴らしつづけた。…
for(僕がこの世を去るまで) { のどかちゃんを愛し続ける; }