簡體   English   中英

在對象構造函數中以編程方式定義Javascript屬性

[英]Programmatically defining Javascript properties in the object constructor

我有一個帶有對象的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)}
            }
        })
    }

我的意圖是使myObj.setting1純粹是一個變量,並且應定義myObj.setting1myObj.setting2 而是,循環嘗試兩次定義myObj._str

未捕獲的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
    })

我從頭開始。 如果您只想使用做一些額外工作的setter和getter,並且每個對象的構造函數中都隱藏了它的存儲,並且您想重用一些泛型函數,則可以執行以下操作:

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通用,並且僅將變量作用域用於值存儲,因為無論如何都需_settingsStore

您誤解了對象文字。

{ _str: blah }是具有名為_str的屬性的對象; 它不使用_str變量的值。

因此,實際上您每次都定義了相同的名稱。
由於您未設置可configurable: true ,因此引發了錯誤。

相反,您應該調用Object.defineProperty (單數),該方法接受一個字符串,后跟一個屬性名稱。
(或者,您可以構建一個對象以傳遞給defineProperties並使用索引器符號為它提供正確的名稱)

但是,您的代碼仍然無法正常工作,因為所有回調都將關閉同一個變量(Javascript沒有塊作用域)。
為了解決這個問題,您需要將每個迭代包裝在單獨的函數中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM