独習JavaScriptのメモ
本はこちら
はじめに
- 今までJavaScriptは、ほぼ雰囲気で使っていた。が、ごまかしがきかなくなってきた。
- ので、(必要に迫られて)本書を手に取った。当初は基礎を総点検するのが目的だった。
- やり始めると知らなこと、理解が曖昧なモノが思いのほか多かった。なのでメモとして残す。
- 実務では利用しなさそうなモノもありそう。だが知識として残す。
7章 スコープ
多分ブラウザ前提のお話
スコープ種類
名前 | 概要 |
---|---|
グローバルスコープ | トップレベルにvarで宣言した変数、関数。 |
スクリプトスコープ | トップレベルにlet,constで宣言した変数、関数。 |
関数スコープ | 関数内に宣言された変数。 |
ブロックスコープ | 構文(ifやwhile文)などのブロック内でlet,constで宣言した変数、関数。 |
モジュールスコープ | ES Modulesの機能が有効なときにトップレベルで宣言した変数、関数。 |
グローバルスコープ、スクリプトスコープとWindowオブジェクト
グローバルスコープに属する変数や関数はWindowオブジェクトのプロパティやメソッドとして値が保持される。
同じくトップレベルにlet,constで宣言した変数、関数はWindowオブジェクトには保持されない。
scope.js
// グローバルスコープ
function foo() {return "global function"};
var bar = "global value";
console.log(window.foo());
// -----> global function
console.log(window.bar);
// -----> global value
// スクリプトスコープ
const baz = function() {return "const baz"};
let qux = "let qux";
console.log(window.baz);
// -----> undefined
console.log(window.qux);
// -----> undefined
モジュールスコープ
モジュールスコープはscriptタグ単位のスコープになる。
scope.js
// モジュールスコープ
<script type="module">
var foo = "module foo1";
</script>
<script type="module">
console.log(foo);
// -----> ここでエラーになる。(グローバルスコープ、スクリプトスコープはエラーとならない)
</script>
クロージャ(Closure)
関数(オブジェクト)が状態を持つこと。通常は実行完了時にメモリ上から破棄される。
ただし、外部のスコープへの参照を持つ関数の場合は破棄されずメモリ上に保持し続ける。
このことをクロージャという。
ふーん、、くらいの感覚でしたが、目的が『カプセル化』と合って納得した。
scope.js
function factory() { // 実行時にcountをインクリメントする関数を返す。
let count = 0;
return function increment() {
console.log(++count) // レキシカルスコープのcountを参照している。
}
}
const foo = factory();
foo();
// -----> 1
foo();
// -----> 2 countが1だった状態を持っているので++countは2となる
foo();
// -----> 3 countが2だった状態を持っているので++countは3となる ... (1)
const bar = factory(); // 関数初期化
bar();
// -----> 1 fooとは異なるオブジェクトなので4とはならず1となる。
foo();
// -----> 4 (1)の状態を保持しているので++countは4となる。barは関係ない。