1

Javascript API を開発しています。その一部の 1 つは、JSON 文字列を受け取り、プログラマーが使用する適切なオブジェクトを構築する JSON デコーダーです。これらのオブジェクトの一部は API の標準ですが、それらのほとんどは、これらの標準オブジェクトのアプリケーションアドホックの子になります。

これらのアプリケーションアドホックオブジェクトは、Javascript 開発の前に自動生成され、名前空間に存在します (その名前はアプリケーションによって異なります)。

これらの JSON 文字列の 1 つが、プロパティが値として持つ{"Foo":{"bar":"Hello world!"}}オブジェクトを生成する可能性があり、生成する必要があるとします。この JSON デコーダーは、 が標準プロトタイプの 1 つであるかどうかをチェックし、そうでない場合は、すべてのアプリケーションのアドホック名前空間をチェックする必要があります (1 つだけであると想定できますが、この質問は複数の名前空間にも当てはまります)。FoobarHello, world!Foo

最初の問題: それらの名前空間を見つけます。いくつかのオプションを見つけてみましょう:

  • オプションの 1 つは、後でチェックするために名前空間を格納する JSON デコーダーでメソッドを作成することです (このメソッドは、これらの名前空間の 1 つが作成されるたびに呼び出す必要があります)。ただし、これらの名前空間を定義するスクリプトでは、JSON デコーダーが既に使用可能になっている必要があるため、いくつかの結合が発生します。私はこれをしたくありません。

  • もう 1 つのオプションは、構築時に名前空間が登録され、デコーダがそこを参照するグローバル変数を持つことです。このオプションは最初のものと非常に似ていますが、グローバル名前空間を汚染します。私はこれをしたくありません。

  • 3 番目のオプションは、何らかの方法でこれらの名前空間にラベルを付けることです。これにより、JSON デコーダーは (読み込み時に)windowそのラベルを持つすべての名前空間を参照してローカルに保存できます。たとえば、これらの名前空間にプロパティを追加することを意味しますIsAFooが、この場合はまったく使用されない値が必要です。次に、単にウィンドウ キーをループし、window[entry].hasOwnProperty("IsAFoo");それらを格納するためにチェックします。面白くない価値があるので、私はこれを望んでいません。

  • 私の最後のオプションは、これらの名前空間を「スーパー名前空間」のインスタンスにすることです。名前空間として機能するオブジェクトがあると想像できます。このスーパー名前空間を継承させることもできますが、必須ではありません。では、この 4 番目のオプションをもう少し拡張してみましょう。これは私が選択したものだからです。

標準 API の一部であり、「スーパー名前空間」と呼ばれるものになるこのオブジェクトがあると想像してください。

var MyCustomQualifier = function (objects) {
    // copy all of the entries to the namespace
    for(var entry in objects) {
        if(objects.hasOwnProperty(entry)) {
            this[entry] = objects[entry];
        }
    }
};

そして、次のような標準 API オブジェクトの 1 つがあるとします。

var SuperFoo = function () {

};

これで、名前空間の名前を含む次のコードが自動生成されます。

var MyGlobalNamespace = MyGlobalNamespace || (function () {
    var Foo = function (bar) {
        this.bar = bar;
    };
    Foo.prototype = new SuperFoo();
    Foo.prototype.constructor = Foo;

    Foo.prototype.say = function () {
        return this.bar;
    };

    return new MyCustomQualifier({
        Foo : Foo
    });
})();

このようにMyGlobalNamespaceして、標準 API オブジェクトを使用してアプリケーションのすべてのオブジェクトを取得し、それにカスタム ビジネス ロジックを与えます。

たとえば、次のコードを実行して、すべてが期待どおりに機能しているかどうかを確認できます。

// this variable would be what the decoder would build,
// but we create it manually here
var foo = new MyGlobalNamespace.Foo("Hello, world!");

console.log("Foo says:", foo.say());
console.log("foo is instance of Foo?", foo instanceof MyGlobalNamespace.Foo);
console.log("foo is instance of SuperFoo?", foo instanceof SuperFoo);

for(var entry in window) {
    if(window[entry] instanceof MyCustomQualifier) {
        console.log(entry + " is a MyCustomQualifier!");
    }
}

次のように出力されます。

Foo says: Hello, world!
foo is instance of Foo? true
foo is instance of SuperFoo? true
MyGlobalNamespace is a MyCustomQualifier!

では、これらの選択肢と 4 番目の選択肢に対する私の答えについてどう思いますか? これを行うための追加の方法はありますか?コードがフレームワークのない純粋な Javascript であることが重要です。

ありがとうございました!

4

0 に答える 0