【问题标题】:How to use a getter to return a read-only nested object?如何使用 getter 返回只读嵌套对象?
【发布时间】:2021-02-15 10:50:32
【问题描述】:

想象一个对象(用于滑块)具有用于自动滚动的嵌套私有对象属性:

let slider = {
    slides: ... ,
    arrows: ... ,
    someMethods(),

    _autoScroll: {
        on: true/false,
        delay: in ms,
        run(),
        stop(),
        somethingElse...
    }
}

我定义了一个 getter/setter,比如:

Object.defineProperty(slider, 'autoScroll', {
        get() {
            return this._autoScroll; (****)
        },
        set(value) {
            if (value.on !== 'undefined') this._autoScroll.on = !!value.on;
            let a = Number(value.delay);
            if ( isFinite(a) && !isNaN(a) ) this._autoScroll.delay = a;
        }
    });

如您所见,我想提供一个机会来设置属性ondelay,如下所示:

slider.autoScroll = {on:true, delay:2000};

问题是在 (****) 行中我可以得到原始嵌套对象 _autoScroll 并且我还可以更改它的属性甚至添加一些新的:

slider.autoScroll.on = 'some Crap';
slider.autoScroll.newProperty = 111;

这会改变原始对象,但我想以只读模式查看整个对象。

其中一个可能的想法是在 getter 中使用JSON.stringify,但这不是我想要的。我想到的另一个选择是返回一个克隆对象,例如:

Object.defineProperties({}, Object.getOwnPropertyDescriptors(obj));

或者只是 Object.assign()。但是太重了,没必要,效果不好!

您认为,有没有什么方法或算法可以有效、快速、美观地完成此任务?最佳实践是什么?也许我根本不应该展示整个对象及其所有属性,因为它是一种反模式?

【问题讨论】:

    标签: javascript getter


    【解决方案1】:

    使用您提到的Object.assign 方法在我看来非常简洁:

    return Object.assign({}, this._autoScroll);
    

    您可以通过展开更简洁地做到这一点:

    return { ...this._autoScroll };
    

    请注意,如果对象属性发生变化,.autoScroll 的调用者将不得不再次调用它,以获取更新的对象数据。

    【讨论】:

      猜你喜欢
      • 2021-02-17
      • 2021-04-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-27
      • 2020-01-26
      • 1970-01-01
      • 2021-10-20
      相关资源
      最近更新 更多