3

私が望むのは、JavaScript プロパティをラップして get/set の動作を変更できる機能です。

値であるプロパティの場合、次のことができます。

var obj = {
    myProperty : 0
};

function notifyOfChange(obj, propertyName) {
    var propertyValue = obj[propertyName];
    Object.defineProperty(obj, propertyName, {
        get : function() { return propertyValue; },
        set : function(newValue) {
            var propertyValue = newValue;
            console.log("Message from notifyOfChange."); 
        }
    });
};

obj.myProperty = 10; // outputs "Message from notifyOfChange."

しかし、myPropertyが既に getter/setter を持っている場合はどうなるでしょうか?

var obj = Object.create({}, {
    myProperty : {
        get : function() { return this._myProperty; },
        set : function(value) {
            console.log("Message from obj itself.");
            this._myProperty = value;
        },
        configurable : true
    }
});

obj.myProperty = 10; // outputs "Message from obj itself";

notifyOfChange(obj, "myProperty");

obj.myProperty = 10; // outputs "Message from notifyOfChange."

myProperty匿名セッターを検出して、 notifyOfChange で呼び出せるようにする方法はありますか?

注: notifyOfChange を任意のオブジェクトで機能させたいので、myPropertyセッターに名前付き関数を使用するだけでは機能しません。

4

1 に答える 1

7
function notifyOfPropertyChange(obj, propertyName) {

    var desc = Object.getOwnPropertyDescriptor(obj, propertyName);

    if ("value" in desc && desc.writable) {
        // Value property

        var propertyValue = obj[propertyName];

        Object.defineProperty(obj, propertyName, {
            get: function () { return propertyValue; },
            set: function (newValue) {
                propertyValue = newValue;
                console.log("Message from notifyOfChange.");
            },
            configurable: true,
            enumerable: desc.enumerable
        });

    } else if (desc.set) {
        // Getter/setter property

        // Redefine the setter, keep the getter if it exists
        var originalSet = desc.set.bind(obj);
        desc.set = function (newValue) {
            originalSet(newValue);
            console.log("Message from notifyOfChange.");
        };
        Object.defineProperty(obj, propertyName, desc);
    }
}

を使用Object.getOwnPropertyNamesして、変更するプロパティ名の完全なリストを取得できます。

Object.getOwnPropertyDescriptorの説明については、MDN を参照してください。

于 2012-04-10T20:40:58.503 に答える