Hatena::ブログ(Diary)

くろまほうさいきょうでんせつ RSSフィード Twitter

2011/03/01 (火)

JSLintとJSHintとhoisting


↓こんな記事を発見。(私がJSLintをフォークしてJSHintを作った理由)
http://anton.kovalyov.net/2011/02/20/why-i-forked-jslint-to-jshint/

ここで話題になってるJSLintを作った人が、今読んでるJavaScript:Good Partsの著者らしいのでちょっと興味が沸いて読んでみた。

JSLint でのチェックができない!

よくあるコードだと思うんですが↓のようなコードをJSLintすると

var myfunc = function() {
	for ( var i = 0; i < 3; i++  ) {
		/* something */
	}
};

↓こんなふうに言われてそれ以降のチェックが行われない。

Error:
Problem at line 2 character 11: Move 'var' declarations to the top of the function.
for ( var i = 0; i < 3; i++ ) {

「varによる定義はfunctionの先頭に持っていくべし」とのこと。

"JSLint can NOT suck it"

ブログの著者が言うには

これを見逃すようにするなオプションはないのでコードを書き換えるかJSLint使うのやめるかしかない。
このエラー&チェック停止はjsコミュニティでも歓迎されていないっぽい。
→ Crockford氏(JSLint作者)駆動ではなく、コミュニティ駆動開発のツールを作ろう
→ JSHint

ということになったらしい。

JSLintが "for(var ..." に文句を言う理由

ブログのコメントをみるとvarを上に持っていけというのにはちゃんと理由があるらしい。

'hoisting'というものがあって・・・
varをfunctionの一番上に持っていかないと発見しづらい問題を起こすことがある。


hoistingってなに?

var foo = 'bar';
(function(){
    if(false){
        var foo = 'BAZ';
    }
    alert(foo);    // bar でも BAZ でもなく... undefined !
})();

↑のコードを実行すると"undefined"とアラートが出る。

         ,. -‐'''''""¨¨¨ヽ
         (.___,,,... -ァァフ|       あ…ありのまま
          |i i|    }! }} //|      今 起こった事を話すぜ!
         |l、{   j} /,,ィ//|
        i|:!ヾ、_ノ/ u {:}//ヘ     『グローバル変数を参照したと
        |リ u' }  ,ノ _,!V,ハ |     思ったら消えていた』
       /´fト、_{ル{,ィ'eラ , タ人 
     /'   ヾ|宀| {´,)⌒`/ |<ヽトiゝ
    ,゙  / )ヽ iLレ  u' | | ヾlトハ〉
     |/_/  ハ !ニ⊇ '/:}  V:::::ヽ 
    // 二二二7'T'' /u' __ /:::::::/`ヽ
   /'´r -―一ァ‐゙T´ '"´ /::::/-‐  \  
   / //   广¨´  /'   /:::::/´ ̄`ヽ ⌒ヽ 
  ノ ' /  ノ:::::`ー-、___/::::://       ヽ  }
_/`丶 /:::::::::::::::::::::::::: ̄`ー-{:::...       イ 

これは

  • alert時のfooは一番近いスコープ(ここでは関数内)のfooを参照しようとする
    • ↑つまり var foo = 'BAZ';
  • このためグローバルにあるfoo(barのほう)は関数内では参照されない
  • でもalertの実行時にはvar foo = 'BAZ';は実行されていない
  • undefined

っていうことらしい

ぶひー。確かにこれのせいで問題が起こってもなかなか見つからなそう・・・
でも

// こういう習慣を
for(var i = 0; i < 3; i++)

// こう変えなさい
var i;
for(i = 0; i < 3; i+=1)

と、急に言われても困るというのはある。。

jsjpjsjp 2011/07/03 03:48 理由は javscript にブロック・スコープがないからだと思うが…

関数スコープしか無いのに、そう見えないから間違えやすい。これを避けるため関数の頭で変数を宣言させる…とな

(現在では let を使うことでブロックスコープも明示的に扱えるけどね)

 2012/11/25 13:36 こんなのIDEレベルで入力した瞬間にCのスコープ規則で推測して重複してそうなら促せばいいくらいの話でlintの思想押しつけんなって感じ
コーディングスタイルを変えろとか本末転倒も甚だしい

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証