js
ECMAScript
jsのコアな部分を言語仕様として切り出したもの。これにより、ブラウザ間の使用を統一できるようになった。
jsの実行環境
jsエンジンはjsコードを実行するためのものであり、ECMAScript以外にも環境により持っている機能が異なる。
ブラウザ環境
jsエンジン = ECMAScript + Web APIs
ブラウザ環境
jsエンジン = ECMAScript + CommonJS
コードの実行
実行前
jsエンジンは下記をあらかじめ準備
コード、グローバルオブジェクト(ブラウザ上ではWindowオブジェクトであり、この中にWeb APIsがある)、this
実行コンテキスト
コードが実行されるときどのような状況で実行されるのか。下記の種類がある。
グローバルコンテキスト
jsファイル直下の実行環境。下記が使用可能。
実行中のコンテキスト内の変数・関数(グローバルスコープ)、グローバルオブジェクト、this
関数コンテキスト
関数が実行されている時に生み出されるコンテキスト。関数宣言内の実行環境。下記が使用可能。
実行中のコンテキスト内の変数・関数(実行中の関数スコープ)、arguments,super,this、外部変数(関数の外で宣言されたもの)
コールスタック
実行中のコードがたどってきたコンテキストの積み重ね。下記のコードの場合、コールスタックは下からグローバル、c、b、aと積み重なる。
関数の処理が終わるとコンテキストは削除され、上から順に削除されることになる
→後入先出しLIFO
function a() {}
function b() {a();}
function c() {b();}
c();
ホイスティング(宣言の巻き上げ)
コンテキスト内で宣言した変数や関数の定義をコード実行前にメモリーに配置すること。
ホイスティングはコンテキストが生成される毎に起こる。
下記は関数の定義前だが、実行前にメモリーに配置されているので実行できる。
a();
function a() {
console.log('a is called');
}
変数の場合は下記のようになる。
console.log(b); // undefined
var b = 0;
このとき、イメージとしては次のようなことが起こっている。最初に変数bのメモリスペースを確保し、undefinedを値としてjsエンジンによって自動で設定する
var b;
console.log(b);
b = 0;
const、let宣言の場合、同じく変数bのメモリスペースを確保するが、undefinedを値として初期化が行われないためエラー発生。
console.log(b); // bの初期化が行われていないエラー発生。
let b = 0;
スコープ
グローバルスコープ
グローバルコンテキスト内でvarでの変数宣言や関数の宣言。宣言したものはwindowオブジェクトに格納される。
呼び出す際は下記のようにwindowをつけてもつけなくても呼び出せる。そのため、windowオブジェクト自体がグローバルスコープのようなものになる。
const a = 1;
console.log(window.a); // console.log(a); と同じ
window.d = 1;
console.log(d); // 1
スクリプトスコープ
グローバルコンテキスト内でletやconsgでの変数宣言。一般的にグローバルスコープと呼ばれる。
関数スコープ
関数コンテキスト内で宣言されたもの。
ブロックスコープ
if文、for文など{}で囲われたもの。関数は関数宣言が前方にあるので関数スコープとなる。
let,constのみ変数宣言で使用する。varや関数宣言を使用するとブロックスコープが無視されるので意図しない挙動になることがある。
レキシカルスコープ
コードを書く場所によって参照できる変数が変わるスコープ。コードを記述した時点で決定するため「静的スコープ」とも言う。
スコープチェーン
スコープが複数階層で連なっている状態。
let a = 2;
function fn1() {
let b = 1;
function fn2() {
let c = 3;
console.log(b);
}
fn2();
}
fn1();
structuredClone
JSDoc
{@link}
指定した名前パスまたは URL へのリンクを作成します。