外で作業する場合、ここでの最初の大きな概念は匿名の機能です。
var Obj = (function() { /* do work */})();
簡単に言えば、無名関数を作成し、すぐにそれを実行して、無名関数からの戻り値をObjという名前の変数に割り当てます。
なぜ誰もがそれをしたいのですか?
この場合、プライベートスコープを作成するために使用されます。javascriptのローカル変数は、それらが定義されている関数にスコープされます。例えば:
function test() {
var a = 10;
}
// a is not defined here.
最後の例では、a
実際にはそれを定義した関数のスコープ内にのみ存在します。var
キーワードを省略することでグローバル変数を定義できるため、Javascriptはこの点で少し注意が必要です。
したがって、あなたが与えた例では、彼らはこの無名関数を使用して、使用されるいくつかの変数のスコープを構築していますが、関数の実行が終了するとすぐに破棄されることを望んでいます。
次:
var Obj = (function() {
function constructor(type, value) {
this.type = type;
this.value = value;
}
// SNIP
})();
これにより、と呼ばれる新しい関数が作成されconstructor
ます。javascript関数はファーストクラスのオブジェクトであることに注意することが重要です。つまり、他のオブジェクトと同じように機能し、変数に割り当てることができます。この関数のスコープは無名関数です。したがって、その機能の範囲外に出ようconstructor
としても機能しません。例えば
var Obj = (function() {
function constructor(type, value) {
this.type = type;
this.value = value;
}
// SNIP
})();
typeof(constructor) // <= undefined
これまでのところ、これまでにスニピットを実行した場合、Obj
定義されていなかったでしょう。それでは、少し先にスキップして終了し、リターンを見てみましょう。
var Obj = (function() {
function constructor(type, value) {
this.type = type;
this.value = value;
}
// SNIP
return constructor;
})();
したがって、無名関数が呼び出されると、コンストラクターが返されます。返されるこの関数はに割り当てられObj
ます。これにより、関数のローカルスコープからコンストラクターが返され、変数に割り当てられます。その後、それを呼び出すことができます
var Obj = (function() {
function constructor(type, value) {
this.type = type;
this.value = value;
}
// SNIP
return constructor;
})();
var o1 = new Obj("t", "v");
o1.type // <= "t"
o1.value // <= "v"
次に、興味深い行があります
var Obj = (function() {
function constructor(type, value) {
this.type = type;
this.value = value;
}
constructor.prototype = { };
// SNIP
return constructor;
})();
これにより、コンストラクターのプロトタイプが空のオブジェクトに設定されます。プロトタイプの詳細を説明することは、この投稿の範囲の一部ですが、過度に単純化すると、プロトタイプは、コンストラクターによって作成されたオブジェクトで使用可能なインスタンスメソッドを定義します。単一の「プロトタイプ」は間で共有され、を呼び出すことによって構築されるオブジェクトで使用できるメソッドを定義するために使用されますnew Obj()
。
次に、ローカルに定義された配列があります
var types = [
"Bool", "Int", "Real", "String", "Name", "Null",
"Array", "Dict", "Stream", "Ref",
"Cmd", "Error", "EOF", "None"
];
関数の内部にいるため、この変数は外部の無名関数のスコープ内にバインドされていることを忘れないでください。
次に、その配列をループして、いくつかのものを設定します。
for (var i = 0; i < types.length; ++i) {
var typeName = types[i];
constructor[typeName] = i;
constructor.prototype["is" + typeName] =
(function (value) {
return this.type == i &&
(typeof value == "undefined" || value == this.value);
});
}
ここでは2つの興味深いことが起こります。まず、から'static'プロパティを設定し、constructor
次にコンストラクターのプロトタイプに新しい関数を作成します。この関数はと呼ばれ"is" + typeName
ます。したがって、「isBool」、「isInt」、「isReal」などの名前のインスタンスメソッドの束を生成する必要があります。
constructor.prototype.lookup = function(key) {
function lookup(key) {
if (!(this.value.contains(key)))
return Obj.nullObj;
return this.value.get(key);
}
}
次に、と呼ばれる別のインスタンスメソッドを定義lookup
し、いくつかの作業を行います。
最後に、コンストラクターからいくつかの静的プロパティを作成し、それらをフリーズします(変更または拡張できないようにするため)
すべてが完了したら、Obj
はコンストラクター関数を指すはずであり、次のように言うことができるはずです。
var myType = new Obj("MyType",undefined);
myType.isBool(undefined) //instance method
Obj.Bool // static property
とにかく、それが使用されていた概念のいくつかを説明するのに少し役立つことを願っています。大きなポイントは、afunction
を使用してスコープを制御できること、および関数がファーストクラスの関数であり、変数のように渡すことができることです。obj.property
ドット表記( )またはブラケット表記()を使用して、オブジェクトからプロパティを参照することもできますobj["property"]
。
学ぶべきことがもっとたくさんあり、本の提案はすべてこのスレッドでしっかりしています。言及されていない場合は、HaverbekeによるEloquentJavaSriptもお勧めします。