1週間近くハマってたのが解決して、嬉しい勢いで殴り書き。初心者仲間の方がいましたら、一緒に考えてみてください。
問題
クッキーから読み出した数字を使って、switch文とif文の分岐をさせようとしていました。
(環境は、Windows10/Microsoft Edge、Google Chrome です)
【元のコード(簡略化してます)】
//変数定義、デフォルト値をセット
var hoge = 10;
var piyo = 20;
//ここからクッキー操作
クッキーを読み出して切り出す;
cookie = 目当てのクッキー(「hoge.piyo」の形で保存してある);
wakeru = cookie.split(".");
hoge = wakeru[0];
piyo = wakeru[1];
//ここからswitch・ifでの操作
switch (hoge){
case 10:
操作hoge0; break;
case 11:
操作hoge1; break;
case 12:
操作hoge2;
}
if (piyo == 20){
動作A;
} else {
動作B;
}
これが、クッキーを読み出したときに、piyoは動くけどhogeが動かないんです。
クッキーが保存されていないとき、すなわちデフォルトの数字のままであれば、hogeも動くので、そこがミソだとは思ったんですが・・・
で、考え込んでダメで、「JavaScript switch 動かない」で検索したら、次のページを見つけました。
回答
JavaScriptの動かないコード (初級編) switch文で,数値以外の変数を評価した時のエラー
型変換を自動的に行なってくれない例として,switch文が挙げられる。
switch文の変数評価の仕組みも知っておく必要がある。
switch文は,引数とcase句が「厳密に等しい」ことを要求する。
参考情報として示されていたURLも踏んでみました。
式と値が一致するかどうかは「==」演算子ではなく「===」演算子によって比較されます。この演算子の違いについては「等価演算子」を参照して下さい。
「===」演算子には次のように比較が行われます。
データ型が異なる場合は無条件でfalseとなります。(以下略)
以上から、クッキーって文字列か!? とひらめいて、文字列を数値に変換する奴「eval()」をセットしてみたら、動きました!!
文字列を整数に変換する関数は「parseInt()」(パースイント)が正しいです。(勉強不足でした)
evalは「文字列をそのままプログラムとして実行する」みたいなやつで、なるべく使わない方が良いです。今回は、数字だけの文字列しか渡してないので、結果的に問題なく動作してましたが。
【直した部分】(ついでにpiyoも数値化した)
//ここからクッキー操作
クッキーを読み出して切り出す;
cookie = 目当てのクッキー(「hoge.piyo」の形で保存してある);
wakeru = cookie.split(".");
hoge = eval(wakeru[0]);
piyo = eval(wakeru[1]);
よくみたら、手持ちのリファレンス本に、「cookieに保存できるデータはテキストのみ」と書いてありました。でも、だから何が起きるかってことが分からないんですよね。エスケープ処理は大事だよ! って事なら色々なところに書いてあるんですが。(今回のは数字なので、エスケープは関係ないです)
また、piyoの動作に問題がなかったことから、if文は厳密な比較はされないことも分かります。のは、if文で使用している「==」がそのまま評価されたから、だと再認識します。
まとめ
・cookieは文字列である! 数字に見えても文字列なのである
・switch文はデータ型まで見てる!(===)
・if文はデータ型まで見てない。(==)使う演算子次第。(==ならデータ型まで見ない)
JavaScriptは、データ型の変換をある程度自動でやってくれるので、楽ちんな面もありますが、たまにこうやってハマるんですね。ということを学びました。
7/21追記:理解が変だと思ったところ(if文まわり)を訂正しました。
余談:
どうでもいいけどhogeとかpiyoって楽しいです。メタ構文変数というそうです。
「サンプルプログラムなどで意味のない名前が必要な場合に利用される、「意味のない名前」であることが広く知られた識別子のことである」メタ構文変数 – Wikipediaより
関連記事
コメント