I have a class that represents a fence, internally its made up from rectangle and circle marker objects (also my classes). The fence has 4 variables - x1, x2, y1 and y2. If any of these changes I have to modify or rebuild the internal marker objects.
Storing and checking the 4 values isn't such a big deal but this is just the first of my world object classes and there will be ones with much longer lists of variables. Is there any good way of checking whether any of these has changed or trigger something on change without explicitly storing double values and checking each time the canvas is redrawn? Something like a property in vb.net or such?
The hasOwnProperty() method will check if an object contains a direct property and will return true or false if it exists or not. The hasOwnProperty() method will only return true for direct properties and not inherited properties from the prototype chain.
The Object.is() method determines whether two values are the same value.
You can use the JavaScript in operator to check if a specified property/key exists in an object. It has a straightforward syntax and returns true if the specified property/key exists in the specified object or its prototype chain. Note: The value before the in keyword should be of type string or symbol .
var fence= {
set x1(){
alert('change');
this.rebuild();
},
rebuild: function(){}
}
Also
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();
Using the object posted 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 multiple properties at once, it will only call the refresh function after all the properties have been set. For example:
fence.x1 = 10;
fence.x2 = 20;
// Outputs: "10,0,20,0 (Outputs only ONCE)"
If we update the y1
property, it will execute the function passed in when creating the property:
fence.y1 = 30;
// Outputs: "Refresh only y1 property."
Refresh Extender:
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;
}
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With