C
C++
JavaScript

JavaScript for文のindex指定方法

VB系やDelphi系をやってきたので、JavaScriptなどのC/C++系のfor文を書くときにループ値の指定方法がいつも、少し引っかかり迷いが生じるのでメモしておきます。

index値が、0から長さ-1までループしてもらいたいときの書き方で単純なものは次の通りです。

i++ や i-- は JsLintに敬意をはらい、使わないようにしてみました。

  var str = 'abc';
  for (var i = 0; i <= str.length - 1; i += 1) {
    console.log(str[i]);
  }
  //a b c と順に出力される

しかし、C系のfor文の言語特性だと思いますが、ループごとにforのループの終了判定の部分

i <= str.length - 1

これが評価されるために、毎度、str.lengthを取得する処理が発生するのでループが少し遅くなります。

なので、高速化を重視して最初にループ回数は変数に代入しておく方がよいとされています。

  var str = 'abc';
  for (var i = 0, il = str.length - 1; i <= il; i += 1) {
    console.log(str[i]);
  }
  //a b c と順に出力される

これはこのようにも書かれます。

  var str = 'abc';
  for (var i = 0, il = str.length; i < il; i += 1) {
    console.log(str[i]);
  }
  //a b c と順に出力される

こうすると、ループの終了値が読み取りにくいので、いまだに自分は少しモヤっとした気分になりますが、C/C++/Java系の人にとっては、可読性が低いということもないのでよく見かけるコードですので、読めるようになっておくといいでしょう。

逆順になると、このように書くとよいです。

  var str = 'abc';
  for (var i = str.length - 1; 0 <= i; i -= 1) {
    console.log(str[i]);
  }
  //c b a と順に出力される

また、工夫してforの構文を利用すると、次のようにもかけます。

  for (var i = str.length; i--;) {
    console.log(str[i]);
  }
  //c b a と順に出力される

動作確認した全文は次のとおり。

index.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title></title>
<script>

  var str = 'abc';

  for (var i = 0; i <= str.length - 1; i += 1) {
    console.log(str[i]);
  }
  //a b c と順に出力される

  for (var i = 0, il = str.length - 1; i <= il; i += 1) {
    console.log(str[i]);
  }
  //a b c と順に出力される

  for (var i = 0, il = str.length; i < il; i += 1) {
    console.log(str[i]);
  }
  //a b c と順に出力される

  for (var i = str.length - 1; 0 <= i; i -= 1) {
    console.log(str[i]);
  }
  //c b a と順に出力される

  for (var i = str.length; i--;) {
    console.log(str[i]);
  }
  //c b a と順に出力される

</script>
</head><body>
</body></html>