前書き
最近、フロントエンドの基礎資料として「JavaScriptコア技術開発 demystified」、「webpack入門から応用まで」...を読みました。これらの本のおかげで、JSやwebpackがフロントエンドの分野で果たす役割について理解が深まりました。これまでは、使い方は知っていても、どのように動作するのか、なぜそのような機能が生まれるのかなど、深いレベルで考えることはなかったかもしれません。本書は「JavaScriptコア技術開発Demystified」から始まり、2つの章に分かれており、最後まで読むと学ぶことができます:
I. 3つの基本データ構造
- スタック
- ヒープ
- キュー これらのデータ構造を過小評価してはいけません。異なる構造とルールによって、一般的に知られている特徴が生まれます:先入れ先出し、オブジェクトの割り当ては参照を渡すこと、メッセージキューなど ...
スタック
- シナリオ1: データ構造、アクセスする方法
- シナリオ2:JSの関数呼び出しスタックと呼ばれるコードの実行順序を指定します。
- シーン3:データの格納場所、ただしJSではヒープ領域とスタック領域を区別していないので、単純にデータはすべてヒープメモリに存在すると考えてよい == FIFO ===先入れ先出し
ヒープ
ヒープ・データ構造は通常ツリー構造です。
var people =
name: 'a',
age: 12,
father: {
name: 'b',
age: 28,
}
;
キュー
JSでは、キューのデータ構造を理解することで、時間ループの仕組みが理解できます。先入れ先出し == FIFO == first-in, first-out == 先入れ先出し == first-in, first-out
第二に、メモリ空間
== JSにはゴミを自動的に回収する仕組みがあります。
基本データ型と変数オブジェクト
最新のes標準では、以下の7つのデータ型が定義されています。
| Boolean | |
| Null | |
| Undefined | |
| Number | |
| Null | |
| Undefined | 現在、多くのブラウザは |
ここからが重要です:
function fn () {
var a = 10;
var b = '11';
var c = null;
}
関数が実行されると、実行環境が作成され、その中に変数オブジェクトVOが作成されます。
彼はまた、スコープチェイニングの原則に関係しているため、上記の段落は、よく理解する必要があります。
参照データ型とメモリ空間
ESで定義された7番目の型:参照データ型 参照データ型Objectはヒープ・メモリに存在し、直接アクセスすることはできません。
var a = 'bar';
var b = a; // 基本型はスタック・メモリ内のデータの直接コピーである。
var c = {p:1};
var d = c; // 参照型はスタック上のデータもコピーするが、このときスタックは実行中の{p:1}ヒープ内のこのオブジェクトのアドレス
メモリ空間の管理
JSは現在、== mark-and-clean アルゴリズムを使用しています:アクセスできないデータはマークされ、再要求されます。注意:ローカルスコープでは、関数の実行が終了するとローカル変数が存在する必要がなくなるので、回収期間を決めるのは簡単で、実行が終了すると回収されます。しかし、グローバルで判断することは困難であるため、グローバル変数を削減し、また、微妙なパフォーマンスを向上させることができます。
実行コンテキスト
この知識ポイントは非常に素晴らしいですが、できる必要があります!の背面にthisより複雑であると考えられていたものを指して、それは明らかです。スコープのチェーンと同様に、変数オブジェクト、アクティビティオブジェクトは、知識のこのポイントに密接に関連しています。
JSの実行では、次の実行コンテキストを入力すると、実行環境のJSは、主に次の3つのケースが含まれます:
| グローバル環境 | コードが実行された後、それは最初のグローバル環境に入ります |
| 関数環境 | 関数コードが実行されると |
| eval | は推奨されません。 |
コンテキストは"スタック"ケースとして扱われます:
// demo.js
function fn1 () {
var n = 999;
function fn2 () {
alert(n);
};
return fn2;
}
var result = fn1();
result(); // 999
上記のコードは、関数スタックに以下の変更を加えます ::::
ライフサイクル
関数が呼び出されると、新しい実行コンテキストが作成され、そのライフサイクルは2つのフェーズに分けられます:
- 作成
- 実行
| 作成 | コンテキストは変数オブジェクトを作成し、スコープチェーンを確認し、thisがそれぞれどこを指しているかを決定します。 |
| 携帯電話 | 作成フェーズの後、コードが実行され、変数の代入や関数の参照などが行われます。 |
覚えるにはまだ図が必要
変数昇格でlet/constが起こらない理由について、もう少し理解する時ではないでしょうか。急ぐ必要はありません!
第四に、変数オブジェクト
作成プロセス
- コンテキストのすべての関数キーワードを順番に取得し、値を代入します。
- コンテキストの変数ライフvarキーワードを順番に取得します。未定義に初期化し、変数が既に存在する場合はスキップされ、元の値は変更されません。
この文章をよく解釈すると、ここでは変数の持ち上げがすべてで、定義された変数は実際には変数オブジェクトの中にあります。そして、varより優先されるのはfunctionであり、varは元の値を上書きすることはできません。
次に、次のケースをよく見てください!!!
var a= 20;
function fn () {console.log('fn')};
function fn () {console.log('cover fn')};
function a() {console.log('cover a')};
console.log(a);
fn();
var fn = 'i want fn';
console.log(fn);
この問題を、作成時と実行時に分けて考えてみましょう。
// 作成するときは、まずfunctionをraiseし、次にvarをraiseする。
function fn () {console.log('fn')};
function fn () {console.log('cover fn')};
function a () {console.log('cover a')};
var a = undefined; // varがすでに存在しているので、グローバル・コンテキストのプロパティをオーバーライドすることはない。
var fn = undefined; // var定義されたfnはすでに存在しているので、上書きされることはない。
//
var a = 20;
console.log(a); //20
fn(); // cover fn
var fn = 'i want cover fn';
console.log(fn); // i want cover fn
!!!varと関数のリフティングの違いを理解し、作成時間と実行時間の役割の違いを理解してください。
グローバル・コンテキストにおける変数オブジェクト
グローバルコンテキストの変数オブジェクトはウィンドウオブジェクトであり、グローバルコンテキストの変数オブジェクトをアクティブにすることはできません!
windowEC = {
VO : window,
scopeChain: [];
this: window;
}
さらに、グローバル・コンテキストはプログラムのライフサイクルと一致しており、他のすべてのコンテキスト環境はグローバル・コンテキストのプロパティに直接アクセスできます。





