为了账号安全,请及时绑定邮箱和手机立即绑定

JS 相当于 Java 的 Collections.unmodifiableCollection

JS 相当于 Java 的 Collections.unmodifiableCollection

FFIVE 2021-06-08 17:58:29
我经常在我的 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有这样的功能吗?如果没有,有人怎么能达到类似的效果(自定义迭代?)
查看完整描述

2 回答

?
萧十郎

TA贡献1815条经验 获得超13个赞

如果您不想复制对象,并且希望确保原始对象不能在外部发生变异,则一种选择是返回一个代理,该代理在任何尝试发生变异时抛出:


const handler = {

  get(obj, prop) {

    return obj[prop];

  },

  set() {

    throw new Error('Setting not permitted');

  }

}

class MyClass {

  _myIds = ['foo', 'bar']

  getIds() {

    return new Proxy(this._myIds, handler);

  }

}


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() {

  return this.myIds as ReadonlyArray<string>;

}


查看完整回答
反对 回复 2021-06-11
  • 2 回答
  • 0 关注
  • 178 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信