我有一个带有TypedArray成员的对象,我想冻结它以防止在设置后修改数据。试图冻结TypedArray或它的ArrayBuffer并没有像我预期的那样表现。我想知道,出于好奇,为什么它的行为方式如此。我正在运行节点4.4.4和Chrome,它的行为或多或少都相同。
var typedArray = new Uint32Array(4);
typedArray[0] = 10;
typedArray[1] = 20;
Object.freeze(typedArray);
// throws TypeError : Cannot freeze array buffer views with elements(...)
我接下来尝试的是冻结底层的ArrayBuffer
Object.freeze(typedArray.buffer); // Does not throws errors
Object.isFrozen(typedArray.buffer); // returns true
typedArray[0] = 50; // Successfully modifies the data, despite the buffer is frozen
我知道我可以将我的设计更改为不保留原始缓冲区,并在需要时从数据成员重建它。但我只是对这种行为感到好奇。
由于
答案 0 :(得分:1)
当您注意到时,类型缓冲区是对原始数据的一种引用。类型化缓冲区可以引用原始缓冲区的片段,并且几个类型化缓冲区可以引用原始缓冲区的相同片段。这是可能的,例如使用subarray。这就是为什么冻结类型缓冲区无法保护原始数据不被更改的原因。存储关于原始缓冲区的片段的所有数据都是昂贵的,这些数据被冻结并在每次更改查询期间进行检查。
因此,因为冻结类型缓冲区不能保证数据保留标准的设计者决定禁止冻结类型缓冲区。 让类型缓冲区冻结的另一个解决方案是注意它不保证数据保存。替代实现可以使冻结类型的缓冲区类型的数据只读接口,可以由另一个类型的缓冲区更改。
标准的设计者只选择了实现Object.freeze例程的最简单方法。