简体   繁体   English

在具有自己属性的对象属性上使用getter和setter

[英]Using getter and setter on an object property that has his own properties

I'm fairly new to getters and setters and am looking for a way to listen for changes in an object to store the data immediately, without calling a Save() function everytime a value gets changed. 我对getter和setter还是比较陌生,并且正在寻找一种侦听对象中的更改以立即存储数据的方法,而无需在每次更改值时调用Save()函数。 This is how I do it right now: 我现在是这样的:

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();
        }
    }

Now I would like to optimize this code so everytime a property in myObject.Data is changed, myObject.Save() is executed. 现在,我想所以每次优化的代码在属性myObject.Data改变, myObject.Save()被执行。 The problem I'm experiencing is that it seems only possible to define a getter for a property that has just one value, but not for a property that is an object itself. 我遇到的问题是,似乎只能为只有一个值的属性定义一个吸气剂,而不能为一个对象本身的属性定义一个吸气剂。

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

myObj.Data.a = 2;

This obviously doesn't work since myObj.Data is not an object and doesn't have the same properties as myObj._Data . 这显然不起作用,因为myObj.Data不是对象,并且不具有与myObj._Data相同的属性。

Thanks in advance for any help. 在此先感谢您的帮助。

You are likely interested in the Proxy object. 您可能对Proxy对象感兴趣。

I used a very simple debounce function callHandler in order to avoid calling the onSet method dozens of times during array modifications. 为了避免在数组修改期间多次调用onSet方法,我使用了一个非常简单的防反跳函数callHandler Otherwise, [1, 2, 3].splice(0, 1) would call the set handler once per item in the original array. 否则, [1, 2, 3].splice(0, 1)将对原始数组中的每个项目调用一次设置处理程序。

 '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.bc[0] = 'test 2'; 

I believe you are looking for Defining a getter on existing objects using defineProperty 我相信您正在寻找使用defineProperty在现有对象上定义吸气剂的方法

To append a getter to an existing object later at any time, use Object.defineProperty() . 若要在以后随时将吸气剂附加到现有对象,请使用Object.defineProperty()

 var o = { a:0 } Object.defineProperty(o, "b", { get: function () { return this.a + 1; } }); console.log(ob) // Runs the getter, which yields a + 1 (which is 1) 

For eg: 例如:

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM