【问题标题】:Perform an action after returning from a getter从 getter 返回后执行操作
【发布时间】:2017-09-19 04:56:14
【问题描述】:

我有一个在对象或数组上设置 getter 和 setter 的函数。 我的问题是,如果设置值是一个对象,我无法检测到它的内部变化,但只有在假设它是通过 getter 访问它的情况下才能检测到它。目前 getter 返回对象但是我想在返回 getter 后执行一个操作,无论它是否被更改。

我现在的代码:

set = function(obj, i, val) {
    Object.defineProperty(obj, i, {
        set(newVal) {
            val = newVal
            // react to changes 
            insert(val, i)
        },
        get() {
            return val
            //I want this to run after the object was accessed and possibly changed
            if (typeof val == "object") {
                insert(val, i)
            }
        },
        configurable: true,
        enumerable: true
    })
}

我想到了一种解决方案,即 setTimeout,但是如果删除了 setter 和 getter,setTimeout 可能会导致不需要的行为,我宁愿代码保持同步。

我考虑的另一个想法是在所有对象属性上定义 setter 和 getter,但这会很昂贵。

我该如何解决这个问题?

【问题讨论】:

  • “但是如果 setter 和 getter 被删除,setTimeout 可能会导致不需要的行为” 嗯?
  • 您可以冻结对象或使用 Immutablejs 之类的库,以便更新对象的唯一方法是重新设置。
  • 这听起来像是 X/Y 问题。您要解决的根本问题是什么?
  • 如果使用 delete 关键字重新定义或删除它们,那么 setTimeouts 函数仍然会触发并可以访问该对象
  • 我正在尝试在没有 angularjs 的情况下重新创建 Ng-repeat

标签: javascript return getter-setter


【解决方案1】:

我想到了一个解决方案,就是 setTimeout...

这就是你的做法,或者Promise.resolve().then(...)

...我宁愿代码保持同步。

不能是同步的。您可以在 getter 返回后执行操作,也可以是同步的。你不能同时拥有它。


也就是说,无法保证在使用 getter 后立即执行异步操作会检测到对对象所做的任何操作。考虑:

var o = yourObject.theProperty;
setTimeout(function() {
    o.foo = "bar";
}, 6000);

theProperty 上的 getter 在第一行执行。直到 6 秒后对象才发生变化。

如果您想检测对象的更改,则将其所有属性设置为无法重新配置的 getter/setter 属性,并对您看到的更改采取行动。 (您也可以使用Object.freezeObject.seal 来防止添加新属性。)

如果您希望对象能够具有您尚未定义的属性,但仍想对它们的更改做出反应,则必须使用Proxy,这会带来相应的性能损失。但是对于一组已知的属性,不可配置的 getter/setter 属性可以完成这项工作。

【讨论】:

    猜你喜欢
    • 2013-12-23
    • 2019-11-24
    • 1970-01-01
    • 2019-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-14
    • 1970-01-01
    相关资源
    最近更新 更多