在具有自己属性

时间:2016-12-31 16:02:57

标签: javascript getter-setter

我是getter和setter的新手,我正在寻找一种方法来监听对象中的更改以立即存储数据,而无需在每次更改值时调用Save()函数。这就是我现在这样做的方式:

var myObject = {
    Data: {
        enabled: true,
        show: false
    },
    Save: function () {
        //store myObject.Data to local storage
    },
    Load: function () {
        //load data from local storage and assign it to myObject.Data
    },
    doSomething: function () {
        myObject.Load();
        if (myObject.Data.enabled) {
            myObject.Data.show = true;
            myObject.Save();
        }
    }

现在我想优化此代码,以便每次更改myObject.Data中的属性时,都会执行myObject.Save()。我遇到的问题是,似乎只能为只有一个值的属性定义一个getter,而不能为一个对象本身的属性定义一个getter。

var myObj = {
    _Data: {
        a: 0,
        b: 1,
        c: 3
    },
    set Data (a) {
        console.log(a);
    }
};

myObj.Data.a = 2;

这显然不起作用,因为myObj.Data不是对象,并且与myObj._Data没有相同的属性。

提前感谢您的帮助。

2 个答案:

答案 0 :(得分:3)

您可能对Proxy对象感兴趣。

我使用了一个非常简单的去抖函数callHandler,以避免在数组修改期间调用onSet方法数十次。否则,[1, 2, 3].splice(0, 1)将在原始数组中为每个项调用一次set处理程序。

'use strict';
var myObject = {
    Data: {
        a: [1, 2, 3],
        b: {c: ['test']}
    },
    Save: function() {
        console.log('Save called');
    },
}

function recursiveProxy(target, onSet) {
    // For performance reasons, onSet will only be called one millesecond
    // after the set handler has last been called.
    var timeout;
    function callHandler() {
        clearTimeout(timeout);
        timeout = setTimeout(onSet, 1);
    }

    var recursiveHandler = {
        get: function(target, property) {
            // If the property is something that could contain another object,
            // we want to proxy it's properties as well.
            if (typeof target[property] == 'object' && target[property] != null) {
                return new Proxy(target[property], recursiveHandler);
            }

            return target[property];
        },
        set: function(target, property, value) {
            console.log('Set called - queueing onSet');
            callHandler();
            target[property] = value;
            return true;
        }
    }

    return new Proxy(target, recursiveHandler);
}

myObject.Data = recursiveProxy(myObject.Data, myObject.Save);

myObject.Data.a.splice(0, 1);
myObject.Data.b.c[0] = 'test 2';

答案 1 :(得分:0)

我相信您正在寻找Defining a getter on existing objects using defineProperty

  

要在以后随时将getter附加到现有对象,请使用   Object.defineProperty()

var o = { a:0 }

Object.defineProperty(o, "b", { get: function () { return this.a + 1; } });

console.log(o.b) // Runs the getter, which yields a + 1 (which is 1)

例如:

var Data = {
    enable: true,
    show: false
};

Object.defineProperty(Data, 'doSomething', {
    get: function() {
        // get something;
    },
    set: function(something) {
        // set something
    }
});