猿问

JS 相当于 Java 的 Collections.unmodifiableCollection

我经常在我的 Java 代码中使用这种策略,以使 Collection 仅供外部世界读取,但避免大/经常克隆:


public abstract class MyClass {

    List<Long> myIds;


    public Collection<Long> getIds() {

        return Collections.unmodifiableCollection(this.myIds);

    }

}

我想在我的 JS 类中遵循相同的模式。这将使我的业务逻辑代码更安全、更清晰,因为我将能够在拥有字段的类中控制对我的列表(推送/拼接等)的每次更改。


目前,列表使用“私有”字段,并使用 get-set 函数从外部访问它们。唯一缺少的链接是一些相当于 java 的 Collections.unmodifiableCollection。不会复制整个列表的东西(例如 slice()),并且不会影响原始字段(例如 Object.freeze())。


JS有这样的功能吗?如果没有,有人怎么能达到类似的效果(自定义迭代?)


FFIVE
浏览 179回答 2
2回答

萧十郎

如果您不想复制对象,并且希望确保原始对象不能在外部发生变异,则一种选择是返回一个代理,该代理在任何尝试发生变异时抛出:const handler = {&nbsp; get(obj, prop) {&nbsp; &nbsp; return obj[prop];&nbsp; },&nbsp; set() {&nbsp; &nbsp; throw new Error('Setting not permitted');&nbsp; }}class MyClass {&nbsp; _myIds = ['foo', 'bar']&nbsp; getIds() {&nbsp; &nbsp; return new Proxy(this._myIds, handler);&nbsp; }}const instance = new MyClass();const ids = instance.getIds();console.log(ids);// Error:// ids[2] = 'baz';// Error:// ids.push('baz');当然,instance._myIds在技术上仍然是可见的——如果你想防止这种情况发生,你可以使用类似WeakMap 的东西来确保私有数组真正只在类内部可见。但是代理有点慢。您可能会考虑使用类似于 Typescript 的东西ReadonlyArray- 这样,您可以确保代码不包含任何会在返回数组后改变数组的内容,同时在运行时保持实际代码快速:private myIds = ['foo', 'bar']public getIds() {&nbsp; return this.myIds as ReadonlyArray<string>;}
随时随地看视频慕课网APP

相关分类

JavaScript
我要回答