サイトアイコン 上尾市のWEBプログラマーによるブログ

「脱初心者のJavaScript力を底上げするための本」の感想・備忘録1

kindle本「脱初心者のJavaScript力を底上げするための本」のまとめ。

点数

87点

感想

内容がわかりやすく、とてもいい本だった。
「巻き上げ」「thisの束縛」のことはちゃんと理解できていなかったので勉強になった。

主な内容

無名関数

JavaScriptでは無名関数がよく使われる。 コールバックのような複数回呼び出すことのない関数を定義する際は、無名関数にするのがお作法。

setTimeout(
    function() {
        console.log('hoge');
    },
1000);

変数の巻き上げ

JavaScriptには、スコープ内でvar, let, constを使って宣言された変数はどの場所で宣言しても関数の先頭で宣言されたとみなされる「巻き上げ」という概念が存在する。 これを理解しておかないとハマることがある。

var a = 'hoge';
var f = function() {
    console.log(a); // undefined
    var a = 'fuga';
    console.log(a); // fuga
}
f();

上記の例の場合

var a = 'hoge';
var f = function() {
   var a; 
   console.log(a); // undefined
   a = 'fuga';
   console.log(a); // fuga
} 

として動作する。 巻き上げによる予期せぬ動作を防ぐ方法は「var, let, constによる変数宣言は必ず関数の先頭で行う」「関数内でグローバル変数を参照する場合は引数として渡す」などがある。

即時関数

即時関数は無名関数の一種で、関数全体を括弧で括ったもの。 無名関数と同様に関数の名前を付けずに定義することができ、加えて関数の呼び出しも省略することができる。

(function(){
        alert( 'これが即時関数だ!' );
}());

// 下記でも動作するが、上記が推奨されている
(function(){
        alert( 'これが即時関数だ!' );
})();

即時関数のメリット

グローバルスコープの汚染を防ぐことができる。
※ES2015では使うべきではない。ブロックで囲めばいいだけ。

// これだとnameがグローバルスコープになってしまう
var name = 'hoehoge',
alert(name);

// これだとグローバルスコープが汚れない
(function(){
    var name = 'hoehoge';
    alert(name);
}());

thisの束縛(apply, call)

関数オブジェクトにはapplyメソッド、callメソッドが用意されている。 違いは引数の渡し方が異なるだけ。(配列で渡すか、個別に渡すか)

var val = 10;
function add(a, b) {
    alert(this.val + a + b);
}

// 通常の呼び出し
add(1, 2); // 13

// thisの束縛
var obj = {val: 3};
add.apply(obj, [4, 5]); // 12
add.call(obj, 6, 7); // 16

thisの束縛(bind)

bindメソッドを使ってthisを束縛することもできる。 bindメソッドは関数オブジェクトを生成する。 bindメソッドは引数も束縛することが可能。束縛する引数の数は自由に設定できる。 用途に応じてapply,call,bindの中から最適なメソッドを選択するとよい。

function add(a, b) {
    alert(this.val + a + b);
}
var obj1 = add.bind({val: 50});
var obj2 = add.bind({val: 100}, 8);
var obj3 = add.bind({val: 150}, 9, 10);
obj1(11, 12); // 73
obj2(13); // 121
obj3(); // 169

nullとundefinedの違い

nullとundefinedは似ているが、完全に別物なので注意が必要。決定的な違いは「nullは設定しない限り発生しない」ということ。

オブジェクトを利用して名前空間を実現する

JavaScriptには他言語のような名前空間の仕組みは存在しない。 しかし、オブジェクトを利用して同等の仕組みを実現することができる。

// 名前空間用オブジェクト
var MyNameSpace = {};
MyNameSpace.hoge = 'fuga';
MyNameSpace.getHoge = function() {
    return this.hoge;
}
// 利用
alert(MyNameSpace.getHoge());
モバイルバージョンを終了