Object.watch(),获取新值



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"

我不能只说alert(myObject.aProperty)的原因是因为这意味着这是一个动态代码,将事件处理程序应用于几个,可能未知的对象。

我只是不确定如何动态地获得使用手表方法的属性的新值。我正在为此建立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?

您需要从传递给watch的函数中返回您希望属性具有的值。

myObject.watch("aProperty", function (prop, oldval, newval) {
    propChanged(newVal);
    return newVal;
});

应该做。

请参阅MDN文档了解该函数的完整细节,但相关位是

监视对象中名为prop的属性的赋值,当设置prop时调用handler(prop, oldval, newval),并将返回值存储在该属性中。观察点可以通过返回修改后的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);
        }
    }
};

最新更新