『君が知らないJavaScript(上)-役割ドメインとクローズドパッケージ』学習ノート
4128 ワード
1.コンパイル原理:
(1)コンパイラ、役割ドメイン、エンジン
var a=2
では、コンパイラは次の処理を行います.var a
に遭遇すると、コンパイラは、同じ役割ドメインのセットにすでに名前の変数が存在するかどうかを尋ねます.もしそうであれば、コンパイラは宣言を無視してコンパイルを続行します.それ以外の場合、現在の役割ドメインのセットに新しい変数を宣言し、a
と命名する必要があります.a=2
という付与操作を処理するために使用されるエンジンの実行に必要なコードを生成する.エンジンが実行されると、まず、現在の役割ドメインセットにa
という変数が存在するかどうかを役割ドメインに尋ねます.もしそうなら、エンジンはこの変数を使用します.そうでない場合、エンジンは、変数が見つかるまで、または最外層の役割ドメイン(つまりグローバル役割ドメイン)に到達するまで、外層にネストされた役割ドメインを検索し続けます.【最外層への作用域が見つからない場合、エンジンはReferenceError
異常を放出します.】注意:•エンジン:JavaScriptプログラム全体のコンパイルと実行を最初から最後まで担当します.•コンパイラ:エンジンの親友の一人で、文法分析やコード生成などの汚い仕事を担当しています.(コンパイル:構文解析-構文解析-コード生成.JavaScriptの場合、コンパイルはコード実行前の数マイクロ秒(さらに短い!))をクリックします.役割ドメイン:エンジンのもう一人の親友は、すべての宣言された識別子(変数)からなる一連のクエリーを収集し、維持し、現在実行されているコードのこれらの識別子へのアクセス権を決定する非常に厳しいルールを実施します.
(2)LHS、RHS、ReferenceError、TypeError (p12)
var a = 2
のa
のような値付与動作の左側)であり、それによって値を付与する.console.log(a)
は、a
とconsole.log
の両方に対してRHSクエリを行う必要があります.RHS
異常を放出します.ReferenceError
で変数が見つかった場合、この変数の値を不合理に操作しようとします.たとえば、非関数タイプの値を関数呼び出したり、nullまたはundefinedタイプの値の属性を参照したりすると、エンジンはRHS
異常を放出します.TypeError
が最上位(グローバル役割ドメイン)にもターゲット変数が見つからない場合、グローバル役割ドメインにその名前の変数(グローバル変数)が作成され、エンジンに返されます.LHS
が最上位レベル(グローバル役割ドメイン)でもターゲット変数が見つからない場合、グローバル変数が作成されずに返され、エンジンはLHS
異常を放出します.2.文法の役割ドメイン
ReferenceError
とeval(..)
関数ですが、この2つの方法はエンジンで最適化できないため、性能が低下し、推奨されません.3.関数の役割ドメインとブロックの役割ドメイン
with
、with
、try/catch catch
、let
、const
4.字下げ
var a = 1;
foo();
function foo() {
console.log( a ); // undefined
var a = 2;
}
次のようになります.
function foo() {
var a;
console.log( a ); // undefined
a = 2;
}
var a;
a = 1;
foo();
foo(); // 1
var foo;
function foo() {
console.log(1);
}
foo = function() {
console.log(2);
}
次のようになります.
function foo() {
console.log(1);
}
var foo; // ,
foo(); // 1
foo = function() {
console.log(2);
}
5.作用域閉パッケージ
(1)forサイクルにおけるletの妙用(p 51)
forループヘッダのlet宣言には特殊な動作もあります.この動作は、変数がループ中に一度だけ宣言されるのではなく、反復のたびに宣言されることを示します.その後の各反復は、前の反復の終了時の値を使用してこの変数を初期化します.例:
for(let i=1;i<=5;i++) {
setTimeout(function() {
console.log(i)
},i*1000)
}
次のようになります.
for(var i=1;i<=5;i++) {
let j=i;
setTimeout(function() {
console.log(j)
},j*1000)
}
(2)モジュール(p 53)
モジュールモードは2つの必要条件を備える必要がある:1.外部の閉じた関数が必要です.この関数は少なくとも1回呼び出さなければなりません(呼び出すたびに新しいモジュールインスタンスが作成されます).2.クローズド関数は、少なくとも1つの内部関数を返さなければならない.これにより、内部関数は、プライベート役割ドメイン内でクローズドパッケージを形成し、プライベート状態にアクセスまたは変更することができる.【関数呼び出しから返される、閉パッケージ関数を持たないデータ属性のみのオブジェクトが真のモジュールではない】
function CoolModule() {
var something = "cool";
var another = [1,2,3];
function doSomething() {
console.log(something);
}
function doAnother() {
console.log(another.join());
}
return {
doSomething: doSomething,
doAnother: doAnother
}
}
var foo = CoolModule();
foo.doSomething(); // cool
foo.doAnother(); // 1,2,3