How to determine if an object variable has been changed?

I have a class representing a fence, inside which it consists of marker objects of a rectangle and a circle (also my classes). The fence has 4 variables - x1, x2, y1 and y2. If any of these changes I have to change or rebuild the internal marker objects.

Saving and checking the values ​​of 4 is not such a big deal, but it is just the first of my classes of objects in the world, and will be available with much longer lists of variables. Is there a good way to check if any of them have changed or something has changed, without explicitly storing duplicate values ​​and checking every time you drag the canvas? Something like a property in vb.net or something?

+6
source share
4 answers
var fence= { set x1(){ alert('change'); this.rebuild(); }, rebuild: function(){} } 

Besides

 function Fence(val){ var value = val; this.__defineGetter__("x1", function(){ return value; }); this.__defineSetter__("x1", function(val){ alert('change'); this.rebuild(); }); this.rebuild = function(){}; } var fence = new Fence(); 
+4
source

Using the object located in the code below, you can achieve it quite easily:

 function Fence() { // constructor } Fence.prototype.refresh = function() { // change the refresh code here console.log(this.x1 + "," + this.y1 + "," + this.x2 + "," + this.y2); }; // must be called after the prototype.refresh function is defined RefreshExtender.addRefreshProperties(Fence, [ new RefreshExtender.Property("x1", 0), // propertyName, defaultValue[, refreshFunction] new RefreshExtender.Property("y1", 0, function() { console.log('Refresh only y1 property.'); }), new RefreshExtender.Property("x2", 0), new RefreshExtender.Property("y2", 0) ]); 

Then when using it:

 var fence = new Fence(); fence.x1 = 20; // Outputs: "20,0,0,0" 

Now, if you change several properties at once, it will call the update function only after all the properties are set. For instance:

 fence.x1 = 10; fence.x2 = 20; // Outputs: "10,0,20,0 (Outputs only ONCE)" 

If we update the y1 property, it will execute the passed function when the property is created:

 fence.y1 = 30; // Outputs: "Refresh only y1 property." 

Update expander:

 var RefreshExtender = { addRefreshProperties: function(baseType, properties) { function defineProperty(property) { Object.defineProperty(baseType.prototype, property.name, { get: function() { var val = this["_" + property.name]; if (typeof val === "undefined") { return property.defaultValue; } return val; }, set: function(val) { var shouldRefresh = this["_" + property.name] !== val; this["_" + property.name] = val; if (shouldRefresh) { if (typeof property.refreshFunction === "function") { property.refreshFunction(); } else { this.refresh(); } } }, enumerable: true, configurable: true }); } for (var i = 0, l = properties.length; i < l; i++) { defineProperty(properties[i]); } var oldRefreshFunction = baseType.prototype.refresh; baseType.prototype.refresh = RefreshExtender._executeOnce(oldRefreshFunction); }, Property : function(name, defaultValue, refreshFunction) { this.name = name; this.defaultValue = defaultValue; if (typeof refreshFunction === "function") { this.refreshFunction = RefreshExtender._executeOnce(refreshFunction); } }, _executeOnce : function(originalFunc) { var isRefreshing = false, func = function() { var _this = this; if (!isRefreshing) { isRefreshing = true; setTimeout(function() { isRefreshing = false; originalFunc.call(_this); }, 0); } }; return func; } }; 
+1
source

You can create a closure with access to setter and getter methods, but without direct access to properties. Sort of:

 var fence = function() { var x1, x2, y1, y2; var setX1 = function(x) { if (typeof x == 'undefined') return x1; if (x != x1) alert('It Changed'); x1 = x; }; var setX2 = function(x) { if (typeof x == 'undefined') return x2; if (x != x2) alert('It Changed'); x2 = x; }; var setY1 = function(y) { if (typeof x == 'undefined') return y1; if (y != y1) alert('It Changed'); y1 = y; }; var setY2 = function(y) { if (typeof y == 'undefined') return y1; if (y != y2) alert('It Changed'); y2 = y; }; return { x1: setX1, x2: setX2, y1: setY1, y2: setY2 } }() fence.x1(1); //alerts "It changed" fence.x1(1); //no alert 
0
source

A good approach might be to define a prototype of the fence, rather than using a normal object. For the prototype, you can create setter methods, rather than directly setting an attribute, and use setter methods to track changes to variables.

The prototype would look something like this:

 function fence(x1, x2, x3, x4){ this.x1 = x1; .... this.changedVars = {}; } fence.Prototype.setX1 = function(newVal){ this.x1 = newVal; this.changedVars.x1 = true; }; 

This will collect all changed variables inside. When you run the method (say "rebuildFence"), you must remove the keys that you updated from this.changedVariables . By preserving all setter methods (and getter methods if you are so inclined), the prototype will also reduce memory overhead, since you will not override functions every time you build a fence.

0
source

Source: https://habr.com/ru/post/972202/


All Articles