问题描述
想象一个具有嵌套私有属性的对象(用于滑块)-用于自动滚动的对象:
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;
}
});
如您所见,我想有机会像下面这样设置.on和.delay属性:
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()。但这太重了,没有必要,效果不好!
您认为,是否有任何方法或算法可以有效,快速,美观地完成此任务?最佳做法是什么?也许我根本不应该显示具有其所有属性的整个对象,而是某种反模式?我需要您的经验和建议
谢谢。
解决方法
使用您提到的Object.assign
方法对我来说很简洁:
return Object.assign({},this._autoScroll);
您可以通过传播更加简洁地做到这一点:
return { ...this._autoScroll };
请注意,如果对象属性发生更改,.autoScroll
的调用者将不得不再次调用它以获取更新的对象数据。