JavaScript
初心者
初心者向け
フロントエンド

JavaScriptで初心者がはまりそうなこと

More than 1 year has passed since last update.

フロントエンドの話です。
といってもMEANだとか、最近のフロントエンドだとかの話はしません。
超初心者が動かないと嘆いたときにふと見てもらえたらとそんな感じのあれです。
用は文法とかブラウザとかそんな話。

情報は常に古くなります。鵜呑みにはしないでください。

本題の前に

JavaScriptはバージョンアップしても互換性をなるべく保つように作られている言語です。
時代によって同じ処理に対していくつかの書き方が存在しています。
昔ちょろっと触った人がJavaScript触れるよって任せると、化石みたいなコードが出来上がってきたりします。
コーディング規約のないような、あるいはフロントエンドが軽視されがちな業界は非常に悲惨でレガシーな世界だったりするので、とても大変だったりします。コードレビューで悲惨な目にあったことが実際にあります。
新しい感じにやりたい方は、Nodejsを入れて云々をしていくことをお勧めします。多分、貴方のフロントエンドの世界は一変します。人によっては輝いて見えるかもしれません。それでもIEとDOMからは逃れられませんが。

ブラウザ対応

だいたいIEが悪い。
もしかしたら初心者はそんなこと気にしないかもしれないけど。でもIEが憎いので書きます。
IEは別のブラウザと挙動が違ったり重かったり、仕様に対応していない部分が多かったりします。
Chromeで動くのにIEで動かない何てことは、ざらです。そういったことも対応しないといけない場合は当然出てきます。

  • そもそもサポートしない(趣味ならこれが一番)
  • 大人しくjQueryなどのブラウザ互換を意識したライブラリを使う(これもまぁ)
  • polyfilを使う

そんな感じで逃避しましょう。
余談ですが、IEのグローバルオブジェクトに対してはjQueryですら挙動を保証しなくなりました。
IEはそろそろ滅んだ方がいい。

変数宣言

その変数、var(let, const)つけ忘れてませんか。
varつけ忘れると悲惨です。グローバル変数になります。
グローバル汚染は悪です、いずれ慣れればそう思うようになります。
大人しく "use strict"; の呪文を先頭に書いておきましょう、あなたの平穏は保たれます。
余談ですが、nodeでlet,constを使う場合にも必要です。

forloopのお話

多分、誰しもがはまるかもしれない話。

test.js
for (var i = 0; i < 10; i ++) {
    console.log(i);
    for (var i = 0; i < 5; i ++) {
        console.log(i);
    }
    //012346を無限に吐き続ける
}

この短さだと嵌りませんが、for文内の処理が長いとうっかりやります、そして中々気づきにくいです、動いちゃうので。内側のfor文のiと外側のiのスコープが同じになってしまうからですね。

  • var -> let にする(ブロックスコープ,ES6)
  • i -> j にする

いずれかの処理をすると、正規の挙動をします。

アロー関数

ES6の話。
こいつはthisスコープを保ってくれるもの。
考えれば当たり前の話なんですが、Prototypeに使うとスコープがグローバルになります。
仕様を少し頭に入れてから触りましょう。

//アロー関数 OK!!!!
a.promiseFunc(......).done(() => {......});

//NG!!!!!!
a.prototype = {
    hogehoge : () => {}
}

処理が終わる前に次の処理へ行ってしまう(Promise)

XHRとかAjaxを初めてやると嵌るのではないでしょうか。僕は当然のごとく嵌りました。
そこで、皆大好きPromiseさんの登場です。デザインパターン知ってて聞いたことがある人もいるかもしれません。
基本的にJavaScriptは非同期処理の世界です。Promiseはそれを便利に扱うための抽象的なオブジェクトです。
初心者の方は雑に、非同期処理で実行順序を保ってくれる便利なものくらいの認識でとりあえず納得しておきましょう。
(Promiseの実装ではPub/SubでQueue管理して制御してるとかなんとか)
ここでは表面的に、かなり雑に、一言で述べたいと思います。
Promiseを用いてthen,catchで正常、異常処理を捉えらよう。

//jQueryのAjax
$.ajax({
//設定
}).then(data => {
//終了後の処理
}).catch(err => {
//エラー処理
})
//かなり適当なPromise例
const prom = new Promise(resolve => {
    resolve();
});
prom.then()

もっと詳しく知りたい方は、無料の電子書籍『Promiseの本』やPromiseの実装などを読み解くと良いと思います。
また、新しい記法にasync/awaitというものもあります。

jQueryとDOMとイベント

時代遅れだ、直接DOMを弄るのはアンチパターンだ、使うなという話は置いておきます。
ただしjQuery使わなければいけないという制約がないのであれば、今の時代でこの選択はしない方が良いのかもしれません。
例えば、一つの大きな思想を生み出したReact、あるいはReact Like なフレームワークを選択してみるのも良いかもしれません。

とはいえ、日本では当分消えないと思います。技術的に劣った大きな企業がこれを捨てられないと思うからです。例えば、(信じられないかもしれませんが)Javaを触る人がJunitを知らないとかそういうことが平然と存在してしまう社会なのです。後は、マイナンバーをエクセル手動管理しちゃうとか。
また、IEというボトルネックによって、依然として、ajaxやextendはとても便利なのです。

ここで話したいのは、ajaxやextendの話ではなくて、DOMに関する部分についてです。

イベント発火したのに処理が動かない、そんなお話です。

例えば、あなたはajax後にそのデータを元にTableをjQueryで生成します。
そしてその新しく生成したTableで、clickとかchangeとかそういったイベントをListenしたいのです。

$('#tableId').click(......)//NG
$(document).on('click',......)//OK

将来的に存在する要素に対してはon()を使用しましょう。

XSS

これは常に意識すべきことです。あなたは自身のアプリケーションにscriptが不正に埋め込まれないようにしないといけません。
チャットなど不特定多数の人間が書き込みを行い、それを多数の人間が見る場合は特にです。
あるいはFormなどでサーバに送られる部分でSQLインジェクションなどが行われる可能性があります。
もしかしたら初学者の方は動かすことに精一杯かもしれませんが、不正が行われることがあると頭の片隅に常に入れておくべきです。
いくつかの(ClosureなどでJSが難読化されていない)Webサイトにおいて、scriptの埋め込める状態のものを見たことがあります。埋め込めること自体が危険というわけではないのですが、個人的には常にエスケープするべきだと思います。

とりあえずここまで。書くのに疲れたので……。今後思いついたらメンテします。
これって奴があったら教えてください、目下困り中でもいいです。