JavaScript实现自定义只读集合的核心是:提供符合Symbol.iterator协议的方法并确保内部数据不可修改;需禁用修改接口、冻结数据、隐藏访问路径,且迭代器仅读取不写入。

JavaScript 中实现自定义集合的只读迭代访问,核心是让集合对象提供一个符合 Symbol.iterator 协议的方法,该方法返回一个满足迭代器协议的对象(即具有 next() 方法),且不暴露内部数据的修改能力。关键在于:迭代器本身不提供 return 或 throw(非必需),也不在 next() 中允许写操作;更重要的是,集合的属性和方法不对外暴露修改接口(如无 add、set、clear 等),或显式冻结内部状态。
1. 定义只读集合类并实现 [Symbol.iterator]
集合类自身不提供任何修改方法,仅封装数据,并在 [Symbol.iterator] 中返回一个闭包内的迭代器 —— 该迭代器只读取内部数组/结构,不持有引用或提供写入口。
例如,实现一个只读的整数范围集合 ReadOnlyRange:
class ReadOnlyRange {
constructor(start, end) {
// 内部用私有字段(或闭包)保存不可变数据
this._data = Array.from({ length: Math.max(0, end - start) }, (_, i) => start + i);
}
<p>// 只暴露迭代能力,不暴露 this._data
[Symbol.iterator]() {
let index = 0;
const data = this._data; // 仅拷贝引用,但不暴露 data 本身</p><pre class="brush:php;toolbar:false;">return {
next() {
if (index <p>}
}</p>2. 确保真正只读:冻结数据与隐藏访问路径
仅靠不写修改方法还不够。需防止用户通过其他方式篡改底层数据:
- 用
Object.freeze(this._data)冻结内部数组(适用于简单值) - 避免将
this._data暴露为公共属性(不定义 getter 返回原数组) - 若需更严格隔离,可用
#privateField(私有字段)配合闭包,彻底阻止外部访问
改进示例(使用私有字段):
class ReadOnlyRange {
#data;
constructor(start, end) {
this.#data = Array.from({ length: Math.max(0, end - start) }, (_, i) => start + i);
Object.freeze(this.#data); // 冻结数组本身
}
<p>[Symbol.iterator]() {
let index = 0;
const data = this.#data;</p><pre class="brush:php;toolbar:false;">return {
next() {
return index <p>}
}</p>3. 验证只读性:不能修改,也不能意外泄露
测试是否真正只读:
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
- 尝试
for...of正常遍历 ✅ - 尝试
range.push(99)或range[0] = 100→ 报错或无效 ✅ - 检查
range.hasOwnProperty('_data')或range.#data→ 访问被拒绝 ✅ - 展开运算符
[...range]得到副本,不影响源 ✅
注意:只读指“逻辑只读”——JS 无法完全禁止反射(如 Object.getOwnPropertyNames),但私有字段 + 冻结 + 无 setter 已满足常规场景的安全边界。
4. 扩展:支持 values()、entries() 等标准方法(可选)
若希望行为更接近内置集合(如 Array),可添加只读辅助方法,它们也返回新迭代器:
values() {
return this[Symbol.iterator]();
}
<p>entries() {
let index = 0;
const data = this.#data;
return {
next() {
if (index </p>这些方法不改变状态,仅提供不同视角的只读遍历,且返回的迭代器同样无副作用。
不复杂但容易忽略:只读的关键不在“迭代器多安全”,而在“集合本身不提供写入口 + 内部数据不可篡改”。只要这两点守住,Symbol.iterator 自然就是只读的起点。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










