読者です 読者をやめる 読者になる 読者になる

素人がプログラミングを勉強していたブログ

プログラミング、セキュリティ、英語、Webなどのブログ since 2008

連絡先: すかいぷ:javascripter_  か javascripter あっと tsukkun.net skypeのほうがいいです

JavaScriptで起こりがちなよくあるミスを早期発見する

JavaScript 第5版」のp174のborrowMethods関数について。

function borrowMethods(borrowFrom, addTo) {
  var from = borrowFrom.prototype;
  var to = addTo.prototype;

  for (m in from) {
    if (typeof from[m] != "function") continue;
    to[m] = from[m];
  }
}

一見何の問題もないように見えるが、変数mがグローバルになってしまっている。
for/inやfor(;;)での変数宣言忘れはよくあることだ。
例えばWebKitのVersion 4 Public Beta (5528.17, r44282)現在では、コンソールのkeys関数とvalues関数が、同じようなミスをしていて、変数kがグローバルになってしまっている。
keys

function (o) { var a = []; for (k in o) a.push(k); return a; }

values

function (o) { var a = []; for (k in o) a.push(o[k]); return a; }

こういった単純なバグは、JSLintというツールを使用すると、簡単に発見することができる。
上のborrowMethods関数をこのツールにかけると、

Error:
Implied global: m 6

Problem at line 5 character 8: Bad for in variable 'm'.

for (m in from) {

Problem at line 6 character 39: Expected '{' and instead saw 'continue'.

if (typeof from[m] != "function") continue;

Problem at line 5 character 3: The body of a for in should be wrapped in an if statement to filter unwanted properties from the prototype.

for (m in from) {

というwarningsが検出される。中身は、

  1. mがグローバルになってしまっている
  2. ifにブレースがついていない
  3. for/inで列挙されるプロパティが、自身の所有しているプロパティかどうか調べていない(hasOwnPropertyを使ってチェックしていない)

である。

また、Firefoxで開発している場合は、javascript.options.strictをtrueにすることで、多くの問題を発見することができる。
Firebugを使っている場合、ConsoleのShow JavaScript WarningsとStrict Warningsを有効にする。
例えば、

a = 3;

のようなグローバル変数の汚染(ただしfor/inとforでのグローバル汚染は検出できない)や、

({foo: null,});

といった末尾のコンマ、その他いくつかの問題を検出してくれる。