3

を使用してJavascriptでJavaのこの次の動作をエミュレートしようとしていmootools/Dojoます。クラスの静的変数値で初期化する必要があるインスタンス変数。

Class xyz {
    public static static_constants {
        TEST_CONST1 : "abc";
    }

    private a = static_constants.TEST_CONST1;
}

以下の方法で実行できますが、com.example.test.static_constants.TEST_CONST1上書きしたため、もう存在しませんcom.example.test。ただし、com.example.test.static_constants.TEST_CONST1が以前に定義されていない場合、クラス内での割り当ては失敗します。

com.example.test.static_constants.TEST_CONST1 = "abc";

var com.example.test = new Class ({
    a : com.example.test.static_constants.TEST_CONST1
});

動作する 2 つの回避策:

(I) - クラス内に別のインスタンス変数があります。静的な外部を使用する

var com.example.test = new Class ({
    static_constants : {
        TEST_CONST1 : "abc"
    },
    a : this.static_constants.TEST_CONST1
});

com.example.test.static_constants.TEST_CONST1 = "abc";

(II)クラスが定義された後に静的を再作成します

com.example.test.static_constants.TEST_CONST1 = "abc";

var com.example.test = new Class ({
    a : com.example.test.static_constants.TEST_CONST1
});

com.example.test.static_constants.TEST_CONST1 = "abc";

私は何が欠けていますか?これらの方法はどちらも私にはきれいに見えません。これを行うには、よりクリーンな方法が必要です (extend などを使用しない - クラスがさらに壊れます)。

4

3 に答える 3

3

その場で割り込んで止めてもいいですか。

JavaScript は Java ではありません。JAVA を使用する必要がなくなったという事実は、Java が持っている名前空間と静的およびパターンに関連するがらくたを JavaScript に移行する必要があるという意味ではありません。JavaScript には、物事を行う際のさまざまなパターンがあります。

いずれにせよ、MooTools で物やクラスを整理するための最適なパターンは何かを尋ねておらず、既存のオブジェクトを変更および拡張する方法を知りたいだけなので、次の小さなファクトリを実行できます。

http://jsfiddle.net/vrKX2/4/

var com = {
    example: {
        test: {
            static_constants: {
                TEST_CONST1: "abc"
            }
        }
    }
};

Class.extend({
    fromExisting: function(namespace, constructorObject){
        return Object.append(new this(constructorObject), namespace);
    }
});

// this is non-DRY. It kind of is Object.merge()
com.example.test = Class.fromExisting(com.example.test, {

    a: com.example.test.static_constants.TEST_CONST1,
    initialize: function(){
        console.warn(this.a);
    },
    getStatic: function(what){
        return com.example.test.static_constants[what];
    }
});

var t = new com.example.test();
console.log(Object.getOwnPropertyNames(t)); // no static_constants
console.log(t.a);
console.log(com.example.test.static_constants);
com.example.test.static_constants.TEST_CONST1 = 'bbb';
console.log(t.a);
console.log(t.getStatic('TEST_CONST1'));

Class.fromExistingいくつかのオブジェクトを受け入れ、そのプロパティをクラスコンストラクターオブジェクトに対してマージします(ただし、静的であり、プロトタイプではありません)-ただし、コンストラクターで拡張しているobjを変更することはできません(理由は今はわかりませんが、土曜日です夜)。

AMDのように、より賢明なモジュール命名アプローチ/名前空間を実装constantsし、別の構成オブジェクトで使用する必要があります。2 つの名前空間を混在させる必要はありません。実際、AMD を使用する場合は名前空間をまったく必要としません (ただし、モジュールに名前を付けることができます)。

このファクトリ パターンは使用しないでください。型などを拡張するときに mootools がいかに柔軟であるかを示しているだけです。

代わりに、前述のように、単に行うことができますObject.merge()

com.example.test = Object.merge(new Class({
    a: com.example.test.static_constants.TEST_CONST1,
    initialize: function(){
        console.warn(this.a);
    },
    getStatic: function(what){
        return com.example.test.static_constants[what];
    }
}), com.example.test);

あなたはいくつかの危険な名前空間を扱っているので、深く機能する get/set を使用して Object Type (Object のプロトタイプではない) を拡張することを検討したいので、Daniel Buchner はそれを上陸させようとしましたが、撃墜されました。

https://github.com/mootools/mootools-core/pull/2191/files

これらは、ドット付き文字列からより深い名前空間を作成する苦労を取り除くかもしれません。今楽しんでください。

于 2013-11-08T20:17:09.600 に答える
1

AMD を使用している場合はdefine、 のようなグローバル オブジェクト チェーンを作成せずにモジュールを作成しますcom.example.test。のドキュメントにdeclarestatic objects に関する短いセクションがありますが、概念は簡単です: 返すモジュールから「エクストラ」を掛けることができます。

定義されているモジュールでのみ使用できる定数が必要な場合は、通常の変数を使用してください。モジュールの外部でアクセスする必要がある場合は、返すモジュール オブジェクトからハングアップしてください。これは質問の最初の方法に似ていますが、グローバル オブジェクトの醜いチェーンを含める必要はありません。

于 2013-11-08T17:04:27.107 に答える