I'm fairly new to getters and setters and am looking for a way to listen for changes in an object to store the data immediately, without calling a Save()
function everytime a value gets changed. This is how I do it right now:
var myObject = {
Data: {
enabled: true,
show: false
},
Save: function () {
//store myObject.Data to local storage
},
Load: function () {
//load data from local storage and assign it to myObject.Data
},
doSomething: function () {
myObject.Load();
if (myObject.Data.enabled) {
myObject.Data.show = true;
myObject.Save();
}
}
Now I would like to optimize this code so everytime a property in myObject.Data
is changed, myObject.Save()
is executed. The problem I'm experiencing is that it seems only possible to define a getter for a property that has just one value, but not for a property that is an object itself.
var myObj = {
_Data: {
a: 0,
b: 1,
c: 3
},
set Data (a) {
console.log(a);
}
};
myObj.Data.a = 2;
This obviously doesn't work since myObj.Data
is not an object and doesn't have the same properties as myObj._Data
.
Thanks in advance for any help.
You are likely interested in the Proxy object.
I used a very simple debounce function callHandler
in order to avoid calling the onSet
method dozens of times during array modifications. Otherwise, [1, 2, 3].splice(0, 1)
would call the set handler once per item in the original array.
'use strict'; var myObject = { Data: { a: [1, 2, 3], b: {c: ['test']} }, Save: function() { console.log('Save called'); }, } function recursiveProxy(target, onSet) { // For performance reasons, onSet will only be called one millesecond // after the set handler has last been called. var timeout; function callHandler() { clearTimeout(timeout); timeout = setTimeout(onSet, 1); } var recursiveHandler = { get: function(target, property) { // If the property is something that could contain another object, // we want to proxy it's properties as well. if (typeof target[property] == 'object' && target[property] != null) { return new Proxy(target[property], recursiveHandler); } return target[property]; }, set: function(target, property, value) { console.log('Set called - queueing onSet'); callHandler(); target[property] = value; return true; } } return new Proxy(target, recursiveHandler); } myObject.Data = recursiveProxy(myObject.Data, myObject.Save); myObject.Data.a.splice(0, 1); myObject.Data.bc[0] = 'test 2';
I believe you are looking for Defining a getter on existing objects using defineProperty
To append a getter to an existing object later at any time, use Object.defineProperty() .
var o = { a:0 } Object.defineProperty(o, "b", { get: function () { return this.a + 1; } }); console.log(ob) // Runs the getter, which yields a + 1 (which is 1)
For eg:
var Data = {
enable: true,
show: false
};
Object.defineProperty(Data, 'doSomething', {
get: function() {
// get something;
},
set: function(something) {
// set something
}
});
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.