Edited at

1年目のスタッフ向けにCodePenとVueでクイズを作ってみた

この記事は Vue.js #3 Advent Calendar 2018 の 3 日目の記事です。


はじめに

無事にフロントエンド研修が終わって、各プロジェクトで働いている1年目の皆様。お元気ですか?

そろそろ、先輩のチェックなしで、一人でお仕事ができるようになってきた頃でしょうか。

実は皆さんに、お伝えしなければならないことがあります。

それは、研修生時代にやらなかった、とある学習内容があります。

この学習内容は、技術研修の内容を、厳選に厳選を重ねた結果、「優先順位の関係」で省かれたものです。

今後、様々なお仕事を経験することで、ある程度は獲得できる知識ではあります。

しかし、どんなプロジェクトにアサインされるのかは、会社の都合によるところが大きく、

この学習内容について、簡潔にまとまったサイトや書籍が見つけられませんでした。。。

そこで今回、この場を借りて出題させていただきますね~


ルール

まずは、CodePenに書かれた「HTML」「CSS」「JS」の内容を見てください。

以下の3点について、いろいろ設定を変えています。

・文字の色

・文字の背景色

・文字の内容

See the Pen VueSample by satoshi hayashi (@satoshi_hayashi) on CodePen.

内容を見たら、自分の頭の中で「出力結果」を想像してみてください。

想像できたら「Result」を押して、「自分が想像した結果」と「出力結果」が一致しているか確認してください。

最後に、必ず「問題の解説」が書かれています。

なぜ、その出力結果になるのか?しっかり解説を読んでから、次の問題にお進みください。


フロントエンドQuiz 全12問 の はじまりはじまり~

第1問

See the Pen Vue1 by satoshi hayashi (@satoshi_hayashi) on CodePen.


第1問-解説

HTML5では非推奨になった「bgcolor」属性を使用しています。

「bgcolor」によって、背景色が「red」になっています。

もしかして、初めて見る人もいるかもしれません。

きちんと開発体制が整った現場ですと、まず見ないパターンです。

もしあっても、コードレビューで指摘されて修正されます。

私の感覚で大変恐縮ですが、実際には「bgcolor」属性よりも「width」属性の方がよく見る気がします。

なぜ、そのような古いコードが現在でも見られるのか?

それには、以下のような「深い理由」があります。

・システム開発会社などでは、フロントエンド専門のエンジニアがいないことがある

・システム開発会社などでは、バックエンドのエンジニアが作った「汚いフロントエンドの実装」を、納期を優先するために許してしまう(中小企業のお客様は、システムの中身がどう作られているか、よくわからない)

・エンジニアが1つのプロジェクトに長期で所属し、新しい技術を使えないシチュエーションが長く続いたため、勉強意欲がなくなった

・エンジニアの業務歴が長くなってきて、だんだんと指摘してくれる先輩エンジニアがいなくなり、昔のやり方のままコードを書いている

ということで、現在でも「古い書き方」が混じったコードを見ることがあります。

もし今のプロジェクトで、GitHubのプルリクエストに、厳しいフィードバック受けている方は、大変ありがたいシチュエーションですので、しっかり学んでくださいませ~


第2問

See the Pen Vue2 by satoshi hayashi (@satoshi_hayashi) on CodePen.




第2問-解説

「bgcolor」によって、背景色に「red」を指定しています。

しかし、スタイルシート「background-color」によって「blue」に上書きされています。

第1問で「bgcolor」は「非推奨の属性」ということを書きました。

普段は使用される機会は少ないですが、もし「非推奨属性とスタイルシート」がバッティングした場合、いったいどちらが勝つのか?実際やってみたのがこの問題です。

「非推奨の属性」<「スタイルシート」

というのが今回の答えです。


第3問

See the Pen Vue3 by satoshi hayashi (@satoshi_hayashi) on CodePen.




第3問-解説

「style」属性の「background-color」によって、背景色に「red」を指定しています。

しかし、スタイルシート「background-color」によって「blue」を指定しています。

ここらへんのスタイルの優先順位について、研修中は

「要素」<「クラス」<「ID」

を覚えて、なぜかスタイルが当たらない場合は「style属性」で直接書いたり「!important」を付けよう

と習ってきたかもしれません。

これは「簡略化したルール」で、初心者用の書籍やWebスクールでも、このように教えています。

実は、このルールでも8割くらいは大丈夫なのですが、残りの2割を切り捨てています。

そのため、たまに、なぜかスタイルが適用されないから、「style属性」で直接書いたり「!important」を付けているコードがあります。

業務歴1年目は、それでもかまわないのですが、2年目以降は「詳細なルール」を勉強して、汚いスタイルの上書き合戦を避けなければなりません。

詳細なルールで解説しますと

「background-color: red」は「スタイル属性」ですので、詳細度は「0.1.0.0.0」。

「background-color: blue」は「要素セレクタ」ですので、詳細度は「0.0.0.0.1」。

「0.1.0.0.0」>「0.0.0.0.1」

その結果、詳細度が大きい「background-color: red」が勝ちます。


第4問

See the Pen Vue4 by satoshi hayashi (@satoshi_hayashi) on CodePen.




第4問-解説

第3問では「style属性」の詳細度が大きいことによって、「style属性」の色が表示されていました。

今回は「!important」を付けることによって、「style属性」に勝とうとしています。

それでは、詳細度のチェックをしてみましょう。

「background-color: red」は「スタイル属性」ですので、詳細度は「0.1.0.0.0」。

「background-color: blue」は「要素セレクタ + !important」ですので、詳細度は「1.0.0.0.1」。

「0.1.0.0.0」<「1.0.0.0.1」

その結果、詳細度が大きい「background-color: blue」が勝ちます。

このように「!important」は最強の詳細度「1.0.0.0.0」をプラスします。

そして、ほとんどの場合にスタイルが適用されることになります。

裏を返せば、安易に「!important」を付けると、その後の改修では常に「!important」を付けて上書きする必要が出てきて、ソースがどんどん汚くなってきます。

「!important」は、最終兵器であり、安易に使用すべきではありません。

もし「!important」を使用して良いシチュエーションをあえて挙げるとすれば、

自分でソースを変更できない「外部の広告タグ」のスタイルによって、サイト本体のスタイルが崩れた場合に、他に方法がなくて、仕方なく「!important」を使用します。


第5問

See the Pen Vue5 by satoshi hayashi (@satoshi_hayashi) on CodePen.




第5問-解説

第4問では「!important」の詳細度が大きいことによって、「style属性」が負けました。

今回は「style属性」の方でも「!important」を付けることによって「CSS」側に勝とうとしています。

それでは、詳細度のチェックをしてみましょう。

「background-color: red」は「スタイル属性 + !important」ですので、詳細度は「1.1.0.0.0」。

「background-color: blue」は「要素セレクタ + !important」ですので、詳細度は「1.0.0.0.1」。

「1.1.0.0.0」>「1.0.0.0.1」

その結果、詳細度が大きい「background-color: red」が勝ちます。

このコードは末期状態です。

もし現場のコードがこんな状態になったら、担当のエンジニアは、改修作業にストレスを感じると思われます。

(ブラウザゲームの現場では、実際にあるのですが。。。)


第6問

See the Pen Vue6 by satoshi hayashi (@satoshi_hayashi) on CodePen.




第6問-解説

第5問では「!important」の詳細度が大きいことによって、「style属性」が勝ちました。

今回は、CSS側が反撃した結果になります。

 

本来「style属性」+「!important」の組み合わせは、詳細度「1.1.0.0.0」と最強に近く、「style属性」+「!important」でないと勝てません。

CSS側は「!important」は作れても、「style属性」が作れないため、詳細度「1.1.0.0.0」を超えることができません。

万事休すか?

背景色が「red」のまま、何もできないのかというと、実はそうではありません。

工夫次第で、CSS側から「blue」にすることができます。

そうです、どうしても「red」が勝つなら、勝たせてやればよい。

その「red」を生かしつつ、「色相」をずらして「blue」にしてしまえば良いのです。

※ご参考

右側に書いてある「色相スケール」や「色相環」で見ると分かりやすいです。

色相 - Wikipedia

「色相」はWebデザイナーの方にとっては「色の基礎知識」として、学生時代に勉強した内容かもしれません。

「red」から色相を240度ずらすと「blue」になります。


第7問

See the Pen Vue7 by satoshi hayashi (@satoshi_hayashi) on CodePen.




第7問-解説

「background-image」と「background-color」の宿命の対決です。

今回は、詳細度の大きさは関係ありません。CSSの仕様としてどちらが優先されるかです。

ということで、結果は「background-image」が優先されるようです。

本来「background-image」のサンプルを作るなら、赤色の画像を使用するところです。しかし、画像を準備する手間があったため、横着をしてグラテーションで背景を作りました。


第8問

See the Pen Vue8 by satoshi hayashi (@satoshi_hayashi) on CodePen.




第8問-解説

「computed」を使用して「小数の精度が悪い」というテーマで出題しました。

一見すると「0.3」で「blue」になりそうですが、実は「0.30000000000000004」が合計となり「red」になります。

ということなので、もしJavaScriptで小数の計算をする場合は、一度「10」や「100」を掛けて整数にしてから、最後に「10」や「100」で割り戻すと、きちんとした計算が出ます。

また、「BigNumber.js」という便利なライブラリもありますので、こちらを利用することも検討してみてくださいませ。

BigNumber.js


第9問

See the Pen Vue9 by satoshi hayashi (@satoshi_hayashi) on CodePen.




第9問-解説

JSONが出てきました。一見すると正しそうですが、実は不正なJSON形式です。

実はJSONは、HTMLみたいに「''」と「""」を両方使用できません。「""」のみ使用できます。

もし9行目の内容を、「''」と「""」を入れ替えて書けば、正しいJSONとなります。


第10問

See the Pen Vue10 by satoshi hayashi (@satoshi_hayashi) on CodePen.




第10問-解説

「日付」というJavaScriptで、誰もが一度はハマるポイントです。

今回も一見すると、正しいように見えますが、「result_date」の中身は「1999/9/11 12:13:14」となります。

 

原因は「getMonth()」が「0~11」の値を返すからです。

しかし「getFullYear()」や「getDate()」は「-1」されないため、なぜ「getMonth()」だけそのような動きをするのか、まったく不思議です。


第11問

See the Pen Vue11 by satoshi hayashi (@satoshi_hayashi) on CodePen.




第11問-解説

初見殺しの問題です。一見すると、両方とも「11」になりそうですが、そうはなりません。

 

「age」は単なる数字で、プリミティブ型と呼ばれます。

プリミティブ型は、文字やtrueなどがあり、関数の引数に設定すると、コピーが使用されます。

→「birthday」の内部では「ageのコピー」が使用される。

 

「boy」は連想配列で、オブジェクト型と呼ばれます。

オブジェクト型は、配列や日付などがあり、関数の引数に設定すると、それ自身が使用されます。

→「birthday」の内部では「boyそのもの」が使用される。

 

つまり「ageのコピー」に対して「+1」しても「ageそのもの」には影響しません。

その結果「age」が「10」、「boy.age」が「11」となって、背景色は「red」になります。

第12問

See the Pen Vue12 by satoshi hayashi (@satoshi_hayashi) on CodePen.




第12問-解説

初見殺しの問題です。一見すると、例外が発生して「red」になりそうですが、そうはなりません。

 

実は、「setTimeout」で関数を実行すると、関数内で例外が発生しても、catchでは捕らえられなくなります。

これがもし、「setTimeout(this.work, 0);」ではなく「this.work();」という普通の実行だったら、catchが実行されて「red」になります。


最後に

全12問、大変お疲れ様でございました。

 

「フロントエンドQuiz」の全12問は、

前半は「CSS」寄りの内容、後半は「JS」寄りの内容になっておりました。

 

これは、私の周りだけかもしれませんが、男子は「JS」が得意で「CSS」が苦手、女子は「CSS」が得意で「JS」が苦手という傾向が見られます。

フロントエンドにおいて「CSS」と「JS」は車の両輪です。

もし今回のQuizを通して、何かしら得るものがありましたら、Quizの作者として大変うれしく思っております。