我有一个代表围栏的类,它内部由矩形和圆形标记对象(也是我的类)组成。该围栏有4个变量 - x1、x2、y1和y2。如果其中任何一个更改了,我必须修改或重建内部标记对象。存储和检查这4个值并不是什么大问题,但这只是我的世界对象类中的第一个,以后可能会有更长的变量列表。是否有一种好的方法来检查是否更改了其中任何一个或在更改时触发某些操作,而不是显式地存储双重值并每次重绘画布时都进行检查?是否有类似于vb.net属性的东西?
var fence= {
set x1(){
alert('change');
this.rebuild();
},
rebuild: function(){}
}
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();
__defineGetter__
和__defineSetter__
已经从标准中删除,因此它们可能会在未来的浏览器中失去支持。它们也不存在于IE 10及以下版本中。 - ckerschfunction 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)
]);
var fence = new Fence();
fence.x1 = 20;
// Outputs: "20,0,0,0"
fence.x1 = 10;
fence.x2 = 20;
// Outputs: "10,0,20,0 (Outputs only ONCE)"
y1
属性,它将执行在创建属性时传递的函数:fence.y1 = 30;
// Outputs: "Refresh only y1 property."
刷新扩展器:
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;
}
};
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
function fence(x1, x2, x3, x4){
this.x1 = x1;
....
this.changedVars = {};
}
fence.Prototype.setX1 = function(newVal){
this.x1 = newVal;
this.changedVars.x1 = true;
};
这将在内部收集所有更改的变量。当您运行方法(比如“rebuildFence”)时,您将从this.changedVariables
中删除更新的键。保留所有Setter方法(如果你愿意还可包括Getter方法)在原型上也可以减少内存开销,因为每次构建栅栏时都不必重新定义函数。