TypedArray和ArrayBuffers(node/chrome)上的Object.freeze()无法按预期工作

mat*_*i.o 8 javascript google-chrome node.js typed-arrays

我有一个带有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(...)
Run Code Online (Sandbox Code Playgroud)

我试过的下一件事就是冻结底层的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
Run Code Online (Sandbox Code Playgroud)

我知道我可以改变我的设计,不保留原始缓冲区,并在需要时从数据成员重建它.但我只是对这种行为感到好奇.

谢谢

wan*_*len 6

正如您所注意到的,类型化缓冲区是对原始数据的一种参考。类型化缓冲区可以引用原始缓冲区的一个切片,并且多个类型化缓冲区可以引用原始缓冲区的同一切片。这是可能的,例如使用subarray。这就是冻结类型缓冲区无法保护原始数据不被更改的原因。存储有关冻结的原始缓冲区切片的所有数据并在每次更改查询期间进行检查的成本会很高。

因此,由于冻结类型缓冲区并不能保证数据保存,标准的设计者决定禁止冻结类型缓冲区。另一种让类型化缓冲区被冻结的解决方案,并注明它不保证数据保存。替代实现可以使冻结类型的缓冲区成为数据的只读接口,这些数据可以被另一个类型的缓冲区更改。

该标准的设计者只是选择了实现Object.freeze例程的最简单方法。