1

Firefoxには、それぞれの特定のプロパティが変更されたときにイベントをトリガーするために必要ないくつかのオブジェクトがあります。object.watch()を使用していますが、「this」を使用して変更されたプロパティの値を返すと、最初は古い値を返し、2回目以降は「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)とだけ言えないのは、これがイベントハンドラーをいくつかの、場合によっては未知のオブジェクトに適用する動的コードであることが意図されているためです。

watchメソッドを使用してプロパティの新しい値を動的に取得する方法が正確にわかりません。このためにIEのプロトタイプを設定しているので、そこで機能しないことを心配していません。「これ」と、それがウォッチメソッドの所有者にどのように適用されるかを理解する必要があります。

編集>>

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?
4

1 に答える 1

4

ウォッチに渡す関数から、プロパティに持たせたい値を返す必要があります。

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

それをする必要があります。

関数の詳細については、 MDNドキュメントを参照してくださいが、関連するビットは次のとおりです。

このオブジェクトのpropという名前のプロパティへの割り当てを監視し、が設定さhandler(prop, oldval, newval)れるたびに呼び出して、そのプロパティに戻り値を格納します。ウォッチポイントは、変更されたものを返す(またはを返す)ことにより、値の割り当てをフィルタリング(または無効化)できます。propnewvaloldval

編集

編集したコードは、この方法でうまく機能する可能性があります

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);
        }
    }
};
于 2011-07-26T14:51:22.917 に答える