![](/img/trans.png)
[英]Using getter and setter on an object property that has his own properties
[英]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.get
和Reflect.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.