3

ブラウザでのPDFレンダリングを扱う興味深いプロジェクトをgithubで見つけました。

このトピックに興味があるのでコードを読み込もうとしましたが、JavaScriptの知識が不十分(不十分)であることに気付きました。

次のような構成があります。

var Obj = (function() {
    function constructor(type, value) {
    this.type = type;
    this.value = value;
    }

    constructor.prototype = {
    };

    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);
     });
    }

    constructor.prototype.lookup = function(key) {
      function lookup(key) {
        if (!(this.value.contains(key)))
          return Obj.nullObj;
        return this.value.get(key);
      }
    }

    Object.freeze(constructor.trueObj = new constructor(constructor.Bool, true));
    Object.freeze(constructor.falseObj = new constructor(constructor.Bool, false));
    Object.freeze(constructor.nullObj = new constructor(constructor.Null));
    Object.freeze(constructor.errorObj = new constructor(constructor.Error));
    Object.freeze(constructor.prototype);
    Object.freeze(constructor);

    return constructor;
})();

あなたは上のリンクでそれらのより多くを見ることができます。

プロジェクトのコードを簡単に理解し、後でプロジェクトに貢献できるようにするために学習するリソースを教えてください。

4

5 に答える 5

6

外で作業する場合、ここでの最初の大きな概念は匿名の機能です。

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もお勧めします。

于 2011-08-23T18:58:11.933 に答える
2

Douglas Crockfordの本JavaScript:The Good Partsは、醜い(またはまったく危険な)部分からあなたを遠ざけながら、JavaScriptの力を理解するのに最適な場所です。 彼のウェブサイトには、言語に関する興味深い記事のコレクションもあります。両方をお勧めします。

于 2011-08-23T18:16:49.087 に答える
1

たぶん、これらのリンクのいくつかはあなたを助けるでしょう:

https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Details_of_the_Object_Model、https://developer.mozilla.org/en/Introduction_to_Object-Oriented_JavaScript、https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/ _ _ _ _ Working_with_Objectshttps: //developer.mozilla.org/en/JavaScript/Guide/Inheritance_Revisited 、

于 2011-08-23T18:15:42.647 に答える
1

いくつかのリンクを参照できます

javascript関数に名前を付けてすぐに実行できますか?

http://devlicio.us/blogs/sergio_pereira/archive/2009/02/09/javascript-5-ways-to-call-a-function.aspx

彼らと一緒に学べることを願っています

于 2011-08-23T18:18:51.307 に答える
1

Douglas Crockford(http://www.crockford.com/)、John Resig(http://ejohn.org/blog/)のブログは、中級から上級の概念に役立ちます。他の人のコードを(あなたがしているのと同じように)見ることも役に立ちます。結局のところ、実際にコンセプトを試すことに勝るものはありませんが、そのためには、信頼できるFirebugコンソールが依然として最高です。

于 2011-08-23T18:22:58.347 に答える