ESLint さまさま。
以下が Treat var as Block Scoped (block-scoped-var) ルールで叱られる:
1 for (var i = 0; i < animetypes.length; ++i) {
2 animetypes[i] = animetypes[i].trim().toUpperCase();
3 }
こんな具合に:
1 2394:18 error 'i' used outside of binding context block-scoped-var
2 2394:18 error 'i' used outside of binding context block-scoped-var
3 2394:18 error 'i' used outside of binding context block-scoped-var
4 2394:25 error 'i' used outside of binding context block-scoped-var
5 2394:25 error 'i' used outside of binding context block-scoped-var
6 2394:25 error 'i' used outside of binding context block-scoped-var
7 2394:50 error 'i' used outside of binding context block-scoped-var
8 2394:50 error 'i' used outside of binding context block-scoped-var
9 2394:50 error 'i' used outside of binding context block-scoped-var
10 2395:24 error 'i' used outside of binding context block-scoped-var
11 2395:24 error 'i' used outside of binding context block-scoped-var
12 2395:24 error 'i' used outside of binding context block-scoped-var
13 2395:40 error 'i' used outside of binding context block-scoped-var
14 2395:40 error 'i' used outside of binding context block-scoped-var
15 2395:40 error 'i' used outside of binding context block-scoped-var
Treat var as Block Scoped (block-scoped-var) ルールに書かれてる NG 例だけみてても何言われてるかわからなかったが、「これみれ」に誘導されて JavaScript Scoping and Hoisting を読む。
げっ。 Only functions create a new scope. そうだったのか…。
「スクリプト言語のスコープ規則」はどの言語も何かしら悩ましい側面があって、Python のもなかなかヒドいが、javascript のこれは、なまじ「java」なんてのを冠してるもんだから「c 系言語と同じだろう」と思ってしまうのが罠よなぁ。
まず引用先で書いている通りで、「本当に c 系言語のようにブロックローカルをしたいんであれば」:
1 (function () {
2 for (var i = 0; i < animetypes.length; ++i) {
3 animetypes[i] = animetypes[i].trim().toUpperCase();
4 }
5 }());
とすれば良い、ということになるのだが、今問題にしている「ループ記述」に限って言えば無論この解はバカげている。
なんとなく自分のコードのループ記述方法に統一感がなくて、書ける色んな書き方しちゃってるわけなんだけれど、ここをなんでインデクスループにしたのか、気分が思い出せない。あ、「中身を書き換えたい」からか。forEach でも書ける?:
1 animetypes.forEach(function (_, i) {
2 animetypes[i] = animetypes[i].trim().toUpperCase();
3 });
なんか他の言語に慣れてると気持ち悪い気もするんだけれど、要素内容を変更したいならこういうことかなぁ。
こういうのはどうしてくれようか:
1 var found = false;
2 for (var i = 0; i < detail["gnr"].length; ++i) {
3 if (genres.includes(detail["gnr"][i].toUpperCase())) {
4 found = true;
5 break;
6 }
7 }
8 if (found !== genresincl) {
9 return false;
10 }
うーん、ちょっと後回し。というかこういうシンプルなリニアサーチがなんか書きにくいんだよなぁ、javascript。なんか上手な書き方はないもんなんだろうか? (※末尾の追記参照。)
どうも上で書いたことも「めっちゃくちゃ FAQ」らしいんだけど、同じくループ関係で、やはり ESLint が検出してくれた「知りませんでしたぁ」があった。言うまでもなく(?) for-in の件。
なんか別の調べてたときに google 検索の一覧レベルで日本人がこれについて書いてるのを「一覧で」みた。まぁ「とてつもなく、凄まじく、とんでもなく」有名なんだろうね。まぁびっくりするわいさ。「頼んでない」ものがわんさか芋づるってくるんだから。(Python の dir の振る舞いに近いかもね。)
これも結局「やったね Good!」:
1 for (key in foo) {
2 if (Object.prototype.hasOwnProperty.call(foo, key)) {
3 doSomething(key);
4 }
5 if ({}.hasOwnProperty.call(foo, key)) {
6 doSomething(key);
7 }
8 }
と言うけれど、「だったら forEach とか別のもん使えや」ちぅハナシ。無論アタシは forEach に書き換えた。
ほんと「知らんことだらけだ」ということなんだけど、どうも ESLint のおかげで、一気に色々知ることが出来そうだ、ありがたい。
06:00追記:
なぜないと思い込んだ? find。ので:
1 var found = detail["gnr"].findIndex(function(e) {
2 return genres.includes(e.toUpperCase());
3 }) >= 0;
てだけじゃん、と。
書き忘れたけど「お行儀ツールの警告」は、こういう「より良い書き方への乗り換えを促す好機と考える」という使い方にこそ価値を見出すべき、てことを理解して使いなはれや。(こういうとこ、後輩や同僚を観察してて「ヲィ」と思うのって。)なんてことを「万年 javascript 初心者の癖に」えらそーに口走ってみる。