Yabu.log

ITなどの雑記

JavaScriptパターン第2章ノート

JavaScriptパターン ―優れたアプリケーションのための作法

JavaScriptパターン ―優れたアプリケーションのための作法

4章まで読めたが、アウトプットが捗らない。5章は写経しないと俺の脳みそにはきつい。

補足:即時関数について

本記事では即時関数を利用しています。ピンとこない方は別記事に書いたものを読んでから本記事を読んでみてください。

Javascriptの変数スコープ

関数ごとにスコープを持つか、グローバル変数化のどちらかであるが、プログラミングの鉄則としてグローバル変数は極力使わないほうがいいという前提に立てば、意図せずグローバル変数を作ってしまう事象は極力避けるべきである。

暗黙のグローバルを避けよ

Varを使わない変数宣言は避けるべき。グローバルスコープを意図せず汚染する恐れがあるため

(function(){
  test = "hello" //暗黙のグローバル変数
  console.log(test)
}());

console.log(test); //hello

コード二行目のtestの宣言のvarを略さず影ば以下のようなエラーが出る。

ReferenceError: Can't find variable: test

代入の連鎖は禁止。片方がグローバル変数になる

(function(){
  var b=a="test"
  console.log("a is " + a+ " in function");//test
  console.log("b is " + b+ " in function");//test
}());

console.log("a is " + a+ " outside function");//test
console.log("b is " + b+ " outside function");//エラー(スコープ外)

暗黙的、明示的なグローバル変数の違い

暗黙の変数はdelete演算子で削除できるが 明示的に宣言したグローバル変数は削除でない

暗黙のグローバル変数は変数ではなく グローバルオブジェクトのプロパティとなるため。 変数は削除できないがプロパティは削除できる

var globalVal ="global";

(function(){
   implicitVal = "implict global";
   
}());

//どちらもglobalスコープ
console.log(globalVal);
console.log(implicitVal);

delete globalVal;
delete implicitVal;

console.log(globalVal);//global
console.log(implicitVal);//ReferenceError: Can't find variable: implicitVal

変数の巻き上げ

実に恐ろしい恐ろしい。 一般的に変数は利用箇所の近くで宣言するのが定石だが ES6以前の環境では明示的に関数の先頭に変数を宣言するのが望ましい。let,constの場合はreference errorになるが、巻き上げは起こっているらしい。

var val1 = "test"
console.log(val1); //test
(function(){
  //↓変数の巻き上げ!!!!!↓
  console.log(val1);//undifind
    

  var val1 = "testtest";
  console.log(val1);
}());
console.log(val1)

単独varパターン

ちょっと気持ち悪いが巻き上げによるバグを喰らわないためには致し方ない

(function test(){
  var a=1,b=2,c=3;
  console.log(a+b+c);
}());

eval()はワル

eval関数は引数の文字列をjavascriptのコードとして解析して実行しようとする。 eval("alert('eval is evil!!!!')"); 本書ではJSONのパースにevalを使ってはいけない、という例が出てきた。*1

XSSなどのセキュリティーリスクがあるので注意。

コードの中で eval() が使われているのを見つけたら、「eval() はワル」という呪文を唱えましょう。

余談ですが、この部分はeval() is Evilの有名なダジャレだけど、訳したり説明したりする気が一切ないのがちょっと切ない。

波括弧の位置

細かいイディオムの話は個人の嗜好でしかないと思うし、統一さえ取れて入ればなんでもいいと思うけど、波括弧の前に改行を入れるのはやめた方がいいと思った

function func() {
  return 
    {name: "Batman" };
}
var test  = fund();
console.log(typeof test);//undefined

上記の例だと二行目returnのあとにundifindが補完されreturn undifindとなり、続くオブジェクトリテラルは無視される。

一般的な命名ルール

コンストラクタは大文字始まりのキャメルケース 変数、関数は小文字始まりのキャメルケース

ただし変数にアンダースコアを含めたり、アンダースコアから始めることで変数の意味を補完するノウハウが紹介されていた

ドキュメンテーションについて

JSDoc Toolkitというjavadocのようなものがあり、そちらを利用できる。 多分Eclipseのようにメソッドの上で/**と入力し改行すると、ドキュメントのテンプレートが入るようなプラグインが各エディタにあるはず。昔salesforceのapex開発をしていた時にsublime textに似たようなアドオンを入れた覚えがある。

*1:JSONがオブジェクトリテラルだったという驚くべき話は次回へ続く