2

すべてのフィールドを含むオブジェクトと、それらに読み書きする関数を持つJavascriptコンストラクターがあります。

function myObj(){
    var _settingsStore {
        setting1: 1, //default value
        setting2: 2, //default value
    }

    //gets/sets _settingsStore.settingName, does other stuff
    function _genericSet(settingName, settingValue){}
    function _genericGet(settingName){}

各フィールドの周りにプログラムでプロパティを作成したいと思います:

    for (var _setting in _settingsStore){
        var _str = _setting.toString();
        Object.defineProperties(this, {
            _str: {
                get: function() {return _genericGet(_str)},
                set: function(value) {return _genericSet(_str, value)}
            }
        })
    }

私の意図は、_str を純粋に変数にすることであり、それmyObj.setting1myObj.setting2定義する必要があります。代わりに、ループはmyObj._str2 回定義しようとします。

キャッチされていない TypeError: プロパティを再定義できません: _str

どうしたの?そして、私の望ましい行動を得る方法はありますか?

編集:明確にするために、これは私が効果的に起こしたいことであり、ループの外側で展開されただけです:

Object.defineProperties(this, {
    settings1: {
            get: function() {return _genericGet("settings1")},
            set: function(value) {return _genericSet("settings1", value)}
        },
    settings2: {
            get: function() {return _genericGet("settings2")},
            set: function(value) {return _genericSet("settings2", value)}
        },
        //and so on, if there are more of them
    })
4

2 に答える 2

3

私は最初からやり直しています。追加の作業を行うセッターとゲッターを使用したいだけで、各オブジェクトがコンストラクターに隠されているオンストアを持ち、いくつかの汎用関数を再利用したい場合は、次のようにすることができます。

function myObj(){
    var _settingsStore = {
        setting1: 1, //default value
        setting2: 2, //default value
    }

    for (var _setting in _settingsStore){
        makeGetSet(this, _setting, _settingStore);
    }
}

function makeGetSet(obj, key, store) {
    Object.defineProperty(obj, key, {
        get: function() { return _genericGet(key, store)}
        set: function(val) {_genericSet(key, val, store)}
    })
}

function _genericGet(key, store){
    var val = store[key];
    // manipulate the val
    return val
}
function _genericSet(key, val, store){
    // manipulate the new val
    store[key] = val
}

取得/設定時にどのような操作を行っているのか本当にわかりません。そのため、これの一部は短縮される可能性があります。

また、_settingsStoreとにかく必要なので、ジェネリックを作成し、値のストレージに変数スコープを使用することもできます。

于 2013-05-08T17:26:06.767 に答える
1

オブジェクトリテラルを誤解しています。

{ _str: blah }という名前のプロパティを持つオブジェクト_strです。_str変数の値は使用しません。

したがって、実際には毎回同じ名前を定義していました。
を設定していないためconfigurable: true、エラーが発生しました。

代わりに、Object.defineProperty(singular) を呼び出す必要があります。これは、文字列の後にプロパティ名が続きます。
(または、渡すオブジェクトを構築し、definePropertiesインデクサー表記を使用して正しい名前を付けることができます)

ただし、すべてのコールバックが同じ変数で閉じられるため、コードは正しく動作しません (Javascript にはブロック スコープがありません)。
これを解決するには、各反復を別の関数でラップする必要があります。

于 2013-05-08T16:40:42.510 に答える