簡體   English   中英

使用getter / setter獲取動態對象屬性

[英]Using getter / setter for dynamic object properties

我有一個稱為status的對象,我想跟蹤類的任何狀態。
除了設置各種狀態外,我還想跟蹤這些狀態已激活了多長時間。 現在,這沒有為每個狀態定義第二個屬性來跟蹤時間,這聽起來像是getter / setter

那就是我被困住的地方。 如何使它們具有動態性,以便它們觸發每個status屬性?

 var Person = function(options) { this.name = options.name; var _statusChanged = {}; var _status = {}; // How to make this dynamic? var expr = "isOnfire"; this.status = { get [expr]() { console.log(_statusChanged); return _status[expr]; }, set [expr](val) { _status[expr] = val; _statusChanged[expr] = new Date(); return _status[expr]; } }; }; var John = new Person({ name: "John" }); John.status.isOnfire = true; John.status.hasPinkShirt = true; console.log(John, John.status.isOnfire, John.status.hasPinkShirt); 

如果您有這些列表,只需循環創建吸氣劑/吸氣劑,例如:

this.status = {};
["isOnFire", "hasPinkShirt"].forEach((name) => {
  Object.defineProperty(status, name {
    get() {
      console.log(_statusChanged);
      return _status[name];
    },
    set(val) {
      _status[name] = val;
      _statusChanged[name] = new Date();
      return _status[name];
    }
  });
});

如果它們可以是任何東西 ,那么您將需要使用Proxy對象 使用代理,您可以捕獲所有獲取/設置,而無需事先知道屬性名稱:

this.status = new Proxy(_status, {
    get(target, propKey, receiver) {
        // handle get
        return _status[propKey];
    },
    set(target, propKey, value, receiver) {
        // handle set
        _status[propKey] = value;
        _statusChanged[propKey] = new Date();
        return true; // Tells the proxy the assignment worked
    }
});

(或者您可以使用Reflect.getReflect.set ,但是甚至Firefox都沒有。)

這是一篇詳細介紹代理的文章

這是一個示例,但是您需要在最新版本的Firefox中運行它,因為在野外 ,真正的支持或Proxy仍然很薄,從本質上講,您不能填充/填充代理。

 (function() { "use strict"; var _status = {}; var _statusChanged = {}; var status = new Proxy(_status, { get(target, propKey, receiver) { snippet.log(propKey + " requested"); return _status[propKey]; }, set(target, propKey, value, receiver) { snippet.log(propKey + " set to " + value); _status[propKey] = value; _statusChanged[propKey] = new Date(); return true; // Tells the proxy the assignment worked } }); status.foo = "bar"; snippet.log("foo = " + status.foo); })(); 
 <!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 --> <script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script> 

在使用它們之前,您需要將狀態設置為方法調用,而不是賦值。

您需要一個稱為ECMAScript 6 Proxy的對象。 在Firefox中,默認情況下處於啟用狀態。 有一次它們是在Chrome的“ 實驗性JavaScript ”下實現的,但似乎已被暫時刪除。 請參閱此ES6兼容性表

此代碼在Firefox中有效:

 var output = function(text) { var line = document.createElement('div'); line.innerHTML = text; document.getElementById('output').appendChild(line); } var Person = function(options) { this.name = options.name; var _status = {}; var _statusChanged = {}; this.status = new Proxy(_status,{ get: function(target,property) { return target[property]; }, set: function(target,property,value) { _statusChanged[property] = new Date(); output("set " + property + " to " + value + " at " + _statusChanged[property]); _status[property] = value; } }); this.show = function(property) { output("Property " + property + " is " + _status[property] + " since " + _statusChanged[property]); } }; var John = new Person({ name: "John" }); John.status.isOnfire = true; John.status.hasPinkShirt = true; John.show("isOnfire"); John.show("hasPinkShirt"); 
 <div id="output"></div> 

也許對你有用

http://jsfiddle.net/oksbLyqf/16/

var Person = function (options) {
    this.name = options.name;

    var _statusChanged = {};
    var _status = {};

    var expr = '';

    var addStatusProperty = function (prop) {
        expr = prop;

        Object.defineProperty(otherStatus, expr, {
            get: function () {
                console.log(_statusChanged);
                return _status[expr];
            },
            set: function (val) {
                _status[expr] = val;
                _statusChanged[expr] = new Date();
                return _status[expr];
            }
        });
    };

    var setStatusProperty = function (prop, val) {
        expr = prop;

        if (_status[expr]) {
            otherStatus[expr] = val;
            return _status[expr];
        } else {
            addStatusProperty(expr);
            otherStatus[expr] = val;
            return _status[expr];
        }
    };

    var getStatusProperty = function (prop) {
        expr = prop;

        return _status[expr]
    };

    this.status = {
        addProperty: addStatusProperty,
        setProperty: setStatusProperty,
        getProperty: getStatusProperty
    };

    var otherStatus = this.status;
};

var John = new Person({
    name: "John"
});

John.status.setProperty('isOnfire', true);
John.status.setProperty('hasPinkShirt', true);

console.log(John, John.status.getProperty('isOnfire'), John.status.getProperty('hasPinkShirt'));

暫無
暫無

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

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