在 Firefox 中,我有几个对象需要在每个事件的特定属性发生更改时触发事件。我正在使用object.watch(),但是当我返回使用“this”更改的属性的值时,它会在第一次返回旧值,并在第二次和之后的时间返回“undefined”:
var myObject = {
"aProperty": 1
};
function propChanged(prop) {
alert(prop);
}
myObject.watch("aProperty", function () {
propChanged(this.aProperty);
});
myObject.aProperty = 2;//alerts "1"
myObject.aProperty = 3;//alerts "undefined"
我不能只说警告(myObject.aProperty)的原因是因为这是一个动态代码,它将事件处理程序应用于几个可能未知的对象。
我只是不确定如何使用watch方法动态获取属性的新值。我正在为此设置IE的原型,所以我并不担心它不能在那里工作。我只需要了解“this”以及它如何应用于watch方法的所有者。
编辑>>
这是我用于跨浏览器的新代码,包括IE等原型:
var myObject = {};
if (!Object.prototype.watch) {
Object.prototype.watch = function (prop, handler) {
var oldval = this[prop], newval = oldval,
getter = function () {
return newval;
},
setter = function (val) {
oldval = newval;
return newval = handler.call(this, prop, oldval, val);
};
if (delete this[prop]) { // can't watch constants
if (Object.defineProperty) // ECMAScript 5
Object.defineProperty(this, prop, {
get: getter,
set: setter
});
else if (Object.prototype.__defineGetter__ && Object.prototype.__defineSetter__) { // legacy
Object.prototype.__defineGetter__.call(this, prop, getter);
Object.prototype.__defineSetter__.call(this, prop, setter);
}
}
};
}
if (!Object.prototype.unwatch) {
Object.prototype.unwatch = function (prop) {
var val = this[prop];
delete this[prop]; // remove accessors
this[prop] = val;
};
}
function propChanged(t, p, o, n) {
alert(o);
}
Object.defineProperty(myObject, "aProperty", {value: 2,
writable: true,
enumerable: true,
configurable: true});
myObject.watch("aProperty", propChanged);
myObject.aProperty = 3; //alerts 3
myObject.aProperty = 4; //alerts 4 (n is undefined in propChanged?
答案 0 :(得分:4)
您需要从您传递给观看的函数返回您希望该属性具有的值。
myObject.watch("aProperty", function (prop, oldval, newval) {
propChanged(newVal);
return newVal;
});
应该这样做。
有关函数的完整详细信息,请参阅MDN docs,但相关位是
观察此对象中名为prop的属性的分配,每当
handler(prop, oldval, newval)
设置为并将返回值存储在该属性时调用prop
。监视点可以通过返回修改后的newval
(或返回oldval
)来过滤(或取消)值赋值。
修改
您编辑的代码可能会更好地运作
Object.prototype.watch = function (prop, handler) {
var fromPrototype = !Object.hasOwnProperty.call(this, prop),
val = this[prop],
getter = function () {
return fromPrototype ? Object.getPrototypeOf(this)[prop] : val;
},
setter = function (newval) {
fromPrototype = false;
return val = handler.call(this, prop, val, newval);
};
if (delete this[prop]) { // can't watch constants
if (Object.defineProperty) { // ECMAScript 5
Object.defineProperty(this, prop, {
get: getter,
set: setter,
configurable: true,
enumerable: true
});
} else if (Object.prototype.__defineGetter__ && Object.prototype.__defineSetter__) { // legacy
Object.prototype.__defineGetter__.call(this, prop, getter);
Object.prototype.__defineSetter__.call(this, prop, setter);
}
}
};