From 4d05ad932349553453408e824506fb5c26c28ba3 Mon Sep 17 00:00:00 2001 From: bemself Date: Tue, 19 Nov 2019 22:36:54 +0800 Subject: [PATCH 01/14] init trans of array buffer --- .../01-concat/task.md | 4 +- .../01-arraybuffer-binary-arrays/article.md | 186 +++++++++--------- 2 files changed, 95 insertions(+), 95 deletions(-) diff --git a/4-binary/01-arraybuffer-binary-arrays/01-concat/task.md b/4-binary/01-arraybuffer-binary-arrays/01-concat/task.md index 6710104b2a..5d85dfec7f 100644 --- a/4-binary/01-arraybuffer-binary-arrays/01-concat/task.md +++ b/4-binary/01-arraybuffer-binary-arrays/01-concat/task.md @@ -1,4 +1,4 @@ -# Concatenate typed arrays +# 拼接类型化数组(Concatenate typed arrays) -Given an array of `Uint8Array`, write a function `concat(arrays)` that returns a concatenation of them into a single array. +给定一个 `Uint8Array` 数组,请写一个函数 `concat(arrays)` ,将数组拼接成一个单一数组并返回。 diff --git a/4-binary/01-arraybuffer-binary-arrays/article.md b/4-binary/01-arraybuffer-binary-arrays/article.md index da19f1947c..af4610b1e4 100644 --- a/4-binary/01-arraybuffer-binary-arrays/article.md +++ b/4-binary/01-arraybuffer-binary-arrays/article.md @@ -1,84 +1,84 @@ -# ArrayBuffer, binary arrays +# ArrayBuffer,二进制数组 -In web-development we meet binary data mostly while dealing with files (create, upload, download). Another typical use case is image processing. +在 web 开发中,进行文件处理操作(创建、上传、下载)时,我们通常要用到二进制数据。另一个典型的应用场景便是图像处理。 -That's all possible in JavaScript, and binary operations are high-performant. +JavaScript 中同样也会遇到,而且二进制操作性能也高。 -Although, there's a bit of confusion, because there are many classes. To name a few: -- `ArrayBuffer`, `Uint8Array`, `DataView`, `Blob`, `File`, etc. +不过,由于 JavaScript 中有很多类,会有点容易混淆。稍微列举几个: +- `ArrayBuffer`,`Uint8Array`,`DataView`,`Blob`,`File`,不一而足。 -Binary data in JavaScript is implemented in a non-standard way, compared to other languages. But when we sort things out, everything becomes fairly simple. +与其他语言相比较,JavaScript 中二进制的实现方式不是很标准。但当我们理清楚以后,一切就变得相当简单了。 -**The basic binary object is `ArrayBuffer` -- a reference to a fixed-length contiguous memory area.** +**最基本的二进制对象是 `ArrayBuffer` -- 对固定长度的相邻内存空间的引用。** -We create it like this: +我们如下创建一个 ArrayBuffer: ```js run -let buffer = new ArrayBuffer(16); // create a buffer of length 16 +let buffer = new ArrayBuffer(16); // 创建一个长度为 16 的缓存区 alert(buffer.byteLength); // 16 ``` -This allocates a contiguous memory area of 16 bytes and pre-fills it with zeroes. +这会分配一个 16 字节的连续内存空间,并预填充为 0。 -```warn header="`ArrayBuffer` is not an array of something" -Let's eliminate a possible source of confusion. `ArrayBuffer` has nothing in common with `Array`: -- It has a fixed length, we can't increase or decrease it. -- It takes exactly that much space in the memory. -- To access individual bytes, another "view" object is needed, not `buffer[index]`. +```warn header="`ArrayBuffer` 不是某个东西的数组" +让我们来澄清一个可能的误区。`ArrayBuffer` 完全不同于 `Array`: +- 其长度固定,我们无法增加或减少。 +- 它在内存中就正好占据那些空间。 +- 如要访问单个字节,需要另一个"视图(view)"对象,而不是 `buffer[index]`。 ``` -`ArrayBuffer` is a memory area. What's stored in it? It has no clue. Just a raw sequence of bytes. +`ArrayBuffer` 是一个内存空间。里面储存的是什么呢?它本身并不知道。只是字节的原始序列。 -**To manipulate an `ArrayBuffer`, we need to use a "view" object.** +**如要操作 `ArrayBuffer`,我们需要使用一个"视图(view)"对象。** -A view object does not store anything on it's own. It's the "eyeglasses" that give an interpretation of the bytes stored in the `ArrayBuffer`. +视图对象本身并不存储任何元素,它是一副”眼镜“,透过它来解析存储在 `ArrayBuffer` 中的字节。 -For instance: +例如: -- **`Uint8Array`** -- treats each byte in `ArrayBuffer` as a separate number, with possible values are from 0 to 255 (a byte is 8-bit, so it can hold only that much). Such value is called a "8-bit unsigned integer". -- **`Uint16Array`** -- treats every 2 bytes as an integer, with possible values from 0 to 65535. That's called a "16-bit unsigned integer". -- **`Uint32Array`** -- treats every 4 bytes as an integer, with possible values from 0 to 4294967295. That's called a "32-bit unsigned integer". -- **`Float64Array`** -- treats every 8 bytes as a floating point number with possible values from 5.0x10-324 to 1.8x10308. +- **`Uint8Array`** -- 将 `ArrayBuffer` 中的每个字节视为一个独立的 0 到 255 之间的数字(一个字节是 8 位,因此只能容纳这么多)。该数字称为 "8 位无符号整数"。 +- **`Uint16Array`** -- 将每 2 个字节视为一个 0 到 65535 之间的整数。该数字称为 "16 位无符号整数"。 +- **`Uint32Array`** -- 将每 4 个字节视为一个 0 到 4294967295 之间的整数。该数字称为 "32 位无符号整数"。 +- **`Float64Array`** -- 将每 8 个字节视为一个 5.0x10-3241.8x10308 之间的整数。 -So, the binary data in an `ArrayBuffer` of 16 bytes can be interpreted as 16 "tiny numbers", or 8 bigger numbers (2 bytes each), or 4 even bigger (4 bytes each), or 2 floating-point values with high precision (8 bytes each). +因此,在一个 16 字节的 `ArrayBuffer` 中,其二进制数据可以表示为 16 个 "小数字",或 8 个大点的数字(每个数字 2 个字节),或 4 个更大的数字 (每个数字 4 个字节),或 2 个高精度的浮点数(每个数字 8 个字节)。 ![](arraybuffer-views.svg) -`ArrayBuffer` is the core object, the root of everything, the raw binary data. +`ArrayBuffer` 是核心对象,是所有对象的基础,是原始二进制数据。 -But if we're going to write into it, or iterate over it, basically for almost any operation – we must use a view, e.g: +但是,如果我们想写入值,或遍历之,基本上对于几乎所有的操作,我们必须使用视图(view),比如: ```js run -let buffer = new ArrayBuffer(16); // create a buffer of length 16 +let buffer = new ArrayBuffer(16); // 创建一个长度为 16 的缓存区 *!* -let view = new Uint32Array(buffer); // treat buffer as a sequence of 32-bit integers +let view = new Uint32Array(buffer); // 将缓存区视为一串 32 位整数 -alert(Uint32Array.BYTES_PER_ELEMENT); // 4 bytes per integer +alert(Uint32Array.BYTES_PER_ELEMENT); // 每个整数 4 个字节 */!* -alert(view.length); // 4, it stores that many integers -alert(view.byteLength); // 16, the size in bytes +alert(view.length); // 4,储存了 4 个整数 +alert(view.byteLength); // 16,大小,以字节数计 -// let's write a value +// 让我们写入一个值 view[0] = 123456; -// iterate over values +// 遍历这些值 for(let num of view) { - alert(num); // 123456, then 0, 0, 0 (4 values total) + alert(num); // 123456,然后是 0,0,0 (一共 4 个值) } ``` -## TypedArray +## 类型化数组(TypedArray) -The common term for all these views (`Uint8Array`, `Uint32Array`, etc) is [TypedArray](https://tc39.github.io/ecma262/#sec-typedarray-objects). They share the same set of methods and properities. +所有这些视图(`Uint8Array`、`Uint32Array`等)有一个通用术语是 [TypedArray](https://tc39.github.io/ecma262/#sec-typedarray-objects)。它们都享有同一组方法和属性。 -They are much more like regular arrays: have indexes and iterable. +它们更像普通数组:有索引,可遍历。 -A typed array constructor (be it `Int8Array` or `Float64Array`, doesn't matter) behaves differently depending on argument types. +一个类型化数组(无论是 `Int8Array` 或 `Float64Array`),其构造器因参数类型而异。 -There are 5 variants of arguments: +有 5 种参数变量: ```js new TypedArray(buffer, [byteOffset], [length]); @@ -88,13 +88,13 @@ new TypedArray(length); new TypedArray(); ``` -1. If an `ArrayBuffer` argument is supplied, the view is created over it. We used that syntax already. +1. 如果给定的是 `ArrayBuffer` 参数,则在其上创建视图。我们已经用过该语法了。 - Optionally we can provide `byteOffset` to start from (0 by default) and the `length` (till the end of the buffer by default), then the view will cover only a part of the `buffer`. + Optionally we can provide `byteOffset` to start from (0 by default) and the `length` (till the end of the buffer by default),then the view will cover only a part of the `buffer`. -2. If an `Array`, or any array-like object is given, it creates a typed array of the same length and copies the content. +2. 如果给定的是 `Array`、或任何类似数组的对象,则创建一个相同长度的类型化数组,并复制其内容。 - We can use it to pre-fill the array with the data: + 我们可以通过此构造器用该数据来预填充数组: ```js run *!* let arr = new Uint8Array([0, 1, 2, 3]); @@ -102,14 +102,14 @@ new TypedArray(); alert( arr.length ); // 4 alert( arr[1] ); // 1 ``` -3. If another `TypedArray` is supplied, it does the same: creates a typed array of the same length and copies values. Values are converted to the new type in the process. +3. 如果给定的是另一个 `TypedArray`,也是如此:创建一个相同长度的类型化数组,并复制其内容。数据在此过程中被转换为新的类型。 ```js run let arr16 = new Uint16Array([1, 1000]); *!* let arr8 = new Uint8Array(arr16); */!* alert( arr8[0] ); // 1 - alert( arr8[1] ); // 232 (tried to copy 1000, but can't fit 1000 into 8 bits) + alert( arr8[1] ); // 232 (试图复制 1000,但无法将 1000 放进 8 位字节中。) ``` 4. For a numeric argument `length` -- creates the typed array to contain that many elements. Its byte length will be `length` multiplied by the number of bytes in a single item `TypedArray.BYTES_PER_ELEMENT`: @@ -119,37 +119,37 @@ new TypedArray(); alert( arr.byteLength ); // 8 (size in bytes) ``` -5. Without arguments, creates an zero-length typed array. +5. Without arguments,creates an zero-length typed array. -We can create a `TypedArray` directly, without mentioning `ArrayBuffer`. But a view cannot exist without an underlying `ArrayBuffer`, so gets created automatically in all these cases except the first one (when provided). +We can create a `TypedArray` directly,without mentioning `ArrayBuffer`. But a view cannot exist without an underlying `ArrayBuffer`,so gets created automatically in all these cases except the first one (when provided). -To access the `ArrayBuffer`, there are properties: +To access the `ArrayBuffer`,there are properties: - `arr.buffer` -- references the `ArrayBuffer`. - `arr.byteLength` -- the length of the `ArrayBuffer`. -So, we can always move from one view to another: +因此,我们总是可以从一个视图移动到另一个视图: ```js let arr8 = new Uint8Array([0, 1, 2, 3]); -// another view on the same data +// 同一数据的另一个视图 let arr16 = new Uint16Array(arr8.buffer); ``` -Here's the list of typed arrays: +以下是类型化数组的列表: -- `Uint8Array`, `Uint16Array`, `Uint32Array` -- for integer numbers of 8, 16 and 32 bits. - - `Uint8ClampedArray` -- for 8-bit integers, "clamps" them on assignment (see below). -- `Int8Array`, `Int16Array`, `Int32Array` -- for signed integer numbers (can be negative). -- `Float32Array`, `Float64Array` -- for signed floating-point numbers of 32 and 64 bits. +- `Uint8Array`、`Uint16Array`、`Uint32Array` -- 用于 8、16 和 32 位的整数。 + - `Uint8ClampedArray` -- 用于 8 位整数, "clamps" them on assignment (see below). +- `Int8Array`, `Int16Array`, `Int32Array` -- 用于有符号整数(可以是负数)。 +- `Float32Array`, `Float64Array` -- 用于 32 位和 64 位的有符号浮点数。 -```warn header="No `int8` or similar single-valued types" -Please note, despite of the names like `Int8Array`, there's no single-value type like `int`, or `int8` in JavaScript. +```warn header="无 `int8` 或类似的单值类型" +请注意,尽管有这样的命名 `Int8Array`,在 JavaScript 中并没有像 `int`,或 `int8` 这样的单值。 -That's logical, as `Int8Array` is not an array of these individual values, but rather a view on `ArrayBuffer`. +这在逻辑上也说得通,因为 `Int8Array` 不是这些单一值的数组,而其实是 `ArrayBuffer` 上的视图。 ``` -### Out-of-bounds behavior +### 越界行为 What if we attempt to write an out-of-bounds value into a typed array? There will be no error. But extra bits are cut-off. @@ -173,7 +173,7 @@ Here's the demo: let uint8array = new Uint8Array(16); let num = 256; -alert(num.toString(2)); // 100000000 (binary representation) +alert(num.toString(2)); // 100000000(二进制表示形式) uint8array[0] = 256; uint8array[1] = 257; @@ -184,44 +184,44 @@ alert(uint8array[1]); // 1 `Uint8ClampedArray` is special in this aspect, its behavior is different. It saves 255 for any number that is greater than 255, and 0 for any negative number. That behavior is useful for image processing. -## TypedArray methods +## TypedArray 方法 -`TypedArray` has regular `Array` methods, with notable exceptions. +`TypedArray` 有普通的 `Array` 方法, with notable exceptions. -We can iterate, `map`, `slice`, `find`, `reduce` etc. +我们可以遍历(iterate)、`map`、`slice`、`find`、`reduce`等等。 -There are few things we can't do though: +但有几件事却不能做: -- No `splice` -- we can't "delete" a value, because typed arrays are views on a buffer, and these are fixed, contiguous areas of memory. All we can do is to assign a zero. -- No `concat` method. +- 无 `splice` -- 我们不能"删除"一个值,因为类型数组是缓存区上的视图,是固定的连续内存空间。我们能做的只是赋值 0。 +- 无 `concat` 方法。 -There are two additional methods: +另有其他两个方法: -- `arr.set(fromArr, [offset])` copies all elements from `fromArr` to the `arr`, starting at position `offset` (0 by default). +- `arr.set(fromArr, [offset])` 从 `fromArr` 中复制所有元素到 `arr`,从起始位置 `offset`(默认为 0)开始。 - `arr.subarray([begin, end])` creates a new view of the same type from `begin` to `end` (exclusive). That's similar to `slice` method (that's also supported), but doesn't copy anything -- just creates a new view, to operate on the given piece of data. -These methods allow us to copy typed arrays, mix them, create new arrays from existing ones, and so on. +有了这些方法,我们可以复制类型数组, mix them,从现有数组创建新数组,等等。 -## DataView +## 数据视图(DataView) [DataView](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView) is a special super-flexible "untyped" view over `ArrayBuffer`. It allows to access the data on any offset in any format. -- For typed arrays, the constructor dictates what the format is. The whole array is supposed to be uniform. The i-th number is `arr[i]`. -- With `DataView` we access the data with methods like `.getUint8(i)` or `.getUint16(i)`. We choose the format at method call time instead of the construction time. +- 对于类型数组,构造器决定了其格式。整个数组应该是 uniform。第 i 个数字是 `arr[i]`。 +- 通过 `DataView`,我们用诸如 `.getUint8(i)` 或 `.getUint16(i)` 方法来访问数据。我们在调用方法的时候选择格式,而不是在构造的时候。 -The syntax: +语法为: ```js new DataView(buffer, [byteOffset], [byteLength]) ``` -- **`buffer`** -- the underlying `ArrayBuffer`. Unlike typed arrays, `DataView` doesn't create a buffer on its own. We need to have it ready. -- **`byteOffset`** -- the starting byte position of the view (by default 0). -- **`byteLength`** -- the byte length of the view (by default till the end of `buffer`). +- **`buffer`** -- 底层的 `ArrayBuffer`。与类型数组不同的是,`DataView` doesn't create a buffer on its own. 我们需要事先准备好。 +- **`byteOffset`** -- 视图的起始字节位置(默认为 0)。 +- **`byteLength`** -- 视图的字节长度(默认至 `buffer` 的最末尾)。 -For instance, here we extract numbers in different formats from the same buffer: +例如,我们从同一缓存区提取不同格式的数字: ```js run let buffer = new Uint8Array([255, 255, 255, 255]).buffer; @@ -240,30 +240,30 @@ alert( dataView.getUint32(0) ); // 4294967295 (biggest 32-bit unsigned int) dataView.setUint32(0, 0); // set 4-byte number to zero ``` -`DataView` is great when we store mixed-format data in the same buffer. E.g we store a sequence of pairs (16-bit integer, 32-bit float). Then `DataView` allows to access them easily. +当我们在同一缓存区内存储混合格式的数据时,`DataView` 非常有用。例如,我们存储一个成对序列(16 位整数,32 位浮点数),用 `DataView` 来访问便很容易。 -## Summary +## 总结 -`ArrayBuffer` is the core object, a reference to the fixed-length contiguous memory area. +`ArrayBuffer` 是核心对象,是对固定长度的连续内存空间的引用。 -To do almost any operation on `ArrayBuffer`, we need a view. +几乎任何对 `ArrayBuffer` 的操作,都需要一个视图。 -- It can be a `TypedArray`: - - `Uint8Array`, `Uint16Array`, `Uint32Array` -- for unsigned integers of 8, 16, and 32 bits. - - `Uint8ClampedArray` -- for 8-bit integers, "clamps" them on assignment. - - `Int8Array`, `Int16Array`, `Int32Array` -- for signed integer numbers (can be negative). - - `Float32Array`, `Float64Array` -- for signed floating-point numbers of 32 and 64 bits. -- Or a `DataView` -- the view that uses methods to specify a format, e.g. `getUint8(offset)`. +- 它可以是 `TypedArray`: + - `Uint8Array`, `Uint16Array`, `Uint32Array` -- 用于 8、16 和 32 位无符号整数。 + - `Uint8ClampedArray` -- 用于 8 位整数, "clamps" them on assignment. + - `Int8Array`, `Int16Array`, `Int32Array` -- 用于有符号整数(可以是负数)。 + - `Float32Array`, `Float64Array` -- 用于 32 位和 64 位的有符号浮点数。 +- 或 `DataView` -- 通过方法(methods)来指定格式的视图,例如,`getUint8(offset)`。 -In most cases we create and operate directly on typed arrays, leaving `ArrayBuffer` under cover, as a "common discriminator". We can access it as `.buffer` and make another view if needed. +大多数情况下,我们直接在类型数组上创建和操作,`ArrayBuffer` under cover, as a "common discriminator". 我们可以通过 `.buffer` 来访问它,以及根据需要创建另一个视图。 -There are also two additional terms: -- `ArrayBufferView` is an umbrella term for all these kinds of views. -- `BufferSource` is an umbrella term for `ArrayBuffer` or `ArrayBufferView`. +另有其他两个术语: +- `ArrayBufferView` 是所有这些视图的总称。 +- `BufferSource` 是 `ArrayBuffer` 或 `ArrayBufferView` 的总称。 -These are used in descriptions of methods that operate on binary data. `BufferSource` is one of the most common terms, as it means "any kind of binary data" -- an `ArrayBuffer` or a view over it. +这两个术语用于操作二进制数据的方法描述中。`BufferSource` 是最常用的术语,意为 "任何类型的二进制数据" -- `ArrayBuffer` 或其上的视图. -Here's a cheatsheet: +以下是备忘录(cheatsheet): ![](arraybuffer-view-buffersource.svg) From 6274765767cbd3726ccc78c4a4a0208db49a4371 Mon Sep 17 00:00:00 2001 From: bemself Date: Wed, 20 Nov 2019 22:31:38 +0800 Subject: [PATCH 02/14] update trans for array buffer article --- .../01-arraybuffer-binary-arrays/article.md | 166 +++++++++--------- 1 file changed, 82 insertions(+), 84 deletions(-) diff --git a/4-binary/01-arraybuffer-binary-arrays/article.md b/4-binary/01-arraybuffer-binary-arrays/article.md index af4610b1e4..bf413e8b18 100644 --- a/4-binary/01-arraybuffer-binary-arrays/article.md +++ b/4-binary/01-arraybuffer-binary-arrays/article.md @@ -1,15 +1,15 @@ # ArrayBuffer,二进制数组 -在 web 开发中,进行文件处理操作(创建、上传、下载)时,我们通常要用到二进制数据。另一个典型的应用场景便是图像处理。 +在 web 开发中,我们通常会在处理文件(创建、上传、下载)时遇到二进制数据。另一个典型的应用场景是图像处理。 JavaScript 中同样也会遇到,而且二进制操作性能也高。 -不过,由于 JavaScript 中有很多类,会有点容易混淆。稍微列举几个: -- `ArrayBuffer`,`Uint8Array`,`DataView`,`Blob`,`File`,不一而足。 +不过,由于 JavaScript 中有很多类,会有点容易混淆。仅举几例: +- `ArrayBuffer`,`Uint8Array`,`DataView`,`Blob`,`File` 等。 -与其他语言相比较,JavaScript 中二进制的实现方式不是很标准。但当我们理清楚以后,一切就变得相当简单了。 +与其他语言相比,JavaScript 中二进制的实现方式不是很标准。但当我们理清楚以后,一切就变得相当简单了。 -**最基本的二进制对象是 `ArrayBuffer` -- 对固定长度的相邻内存空间的引用。** +**基本的二进制对象是 `ArrayBuffer` -- 对固定长度的连续内存空间的引用。** 我们如下创建一个 ArrayBuffer: ```js run @@ -17,52 +17,51 @@ let buffer = new ArrayBuffer(16); // 创建一个长度为 16 的缓存区 alert(buffer.byteLength); // 16 ``` -这会分配一个 16 字节的连续内存空间,并预填充为 0。 +它会分配一个 16 字节的连续内存区域,并预先用 0 填充。 -```warn header="`ArrayBuffer` 不是某个东西的数组" -让我们来澄清一个可能的误区。`ArrayBuffer` 完全不同于 `Array`: -- 其长度固定,我们无法增加或减少。 -- 它在内存中就正好占据那些空间。 -- 如要访问单个字节,需要另一个"视图(view)"对象,而不是 `buffer[index]`。 +```warn header ="`ArrayBuffer` 不是某种数组"让我们来澄清一个可能的误区。‎`ArrayBuffer` 与 `Array` 没有任何共同之处: +- 它长度固定,无法增加或减少。 +- 它正好占用了内存中那么多的空间。 +- 如要访问单个字节,需要另一个"视图"对象,而不是 `buffer[index]`。 ``` -`ArrayBuffer` 是一个内存空间。里面储存的是什么呢?它本身并不知道。只是字节的原始序列。 +`ArrayBuffer` 是一个内存区域它里面存储了什么?无从判断。只是一个原始的字节序列。 -**如要操作 `ArrayBuffer`,我们需要使用一个"视图(view)"对象。** +**如要操作 `ArrayBuffer`,我们需要使用"视图"对象。 -视图对象本身并不存储任何元素,它是一副”眼镜“,透过它来解析存储在 `ArrayBuffer` 中的字节。 +视图对象本身并不存储任何元素。它是一副”眼镜“,透过它来解析存储在 `ArrayBuffer` 中的字节。 例如: -- **`Uint8Array`** -- 将 `ArrayBuffer` 中的每个字节视为一个独立的 0 到 255 之间的数字(一个字节是 8 位,因此只能容纳这么多)。该数字称为 "8 位无符号整数"。 -- **`Uint16Array`** -- 将每 2 个字节视为一个 0 到 65535 之间的整数。该数字称为 "16 位无符号整数"。 -- **`Uint32Array`** -- 将每 4 个字节视为一个 0 到 4294967295 之间的整数。该数字称为 "32 位无符号整数"。 -- **`Float64Array`** -- 将每 8 个字节视为一个 5.0x10-3241.8x10308 之间的整数。 +- **`Uint8Array`** -- 将 "ArrayBuffer" 中的每个字节视为 0 到 255 之间的单个数字(每个字节是 8 位,因此只能容纳那么多)。此类值称为 "8 位无符号整数"。 +- **`Uint16Array`** -- 将每 2 个字节视为一个 0 到 65535 的整数。此类值称为"16 位无符号整数"。 +- **`Uint32Array`** -- 将每 4 个字节视为一个 0 到 4294967295 之间的整数。此类值称为"32 位无符号整数"。 +- **`Float64Array`** -- 将每 8 个字节视为一个 5.0x10-3241.8x10308 之间的浮点数。 -因此,在一个 16 字节的 `ArrayBuffer` 中,其二进制数据可以表示为 16 个 "小数字",或 8 个大点的数字(每个数字 2 个字节),或 4 个更大的数字 (每个数字 4 个字节),或 2 个高精度的浮点数(每个数字 8 个字节)。 +因此,一个 16 字节 `ArrayBuffer` 中的二进制数据可以表示为 16 个"小数字",或 8 个较大的数字(每个数字 2 个字节),或 4 个更大的数字 (每个数字 4 个字节),或 2 个高精度的浮点数(每个数字 8 个字节)。 ![](arraybuffer-views.svg) `ArrayBuffer` 是核心对象,是所有对象的基础,是原始二进制数据。 -但是,如果我们想写入值,或遍历之,基本上对于几乎所有的操作,我们必须使用视图(view),比如: +但是,如果我们要写入值,或遍历之,基本上几乎任何操作 - 我们必须使用视图(view),例如: ```js run -let buffer = new ArrayBuffer(16); // 创建一个长度为 16 的缓存区 +let buffer = new ArrayBuffer(16); // 创建长度为 16 的缓存区 *!* -let view = new Uint32Array(buffer); // 将缓存区视为一串 32 位整数 +let view = new Uint32Array(buffer); // 将缓存区视为 32 位整数序列 alert(Uint32Array.BYTES_PER_ELEMENT); // 每个整数 4 个字节 */!* alert(view.length); // 4,储存了 4 个整数 -alert(view.byteLength); // 16,大小,以字节数计 +alert(view.byteLength); // 16,大小为 16,以字节为单位 // 让我们写入一个值 view[0] = 123456; -// 遍历这些值 +// 遍历值 for(let num of view) { alert(num); // 123456,然后是 0,0,0 (一共 4 个值) } @@ -71,12 +70,12 @@ for(let num of view) { ## 类型化数组(TypedArray) -所有这些视图(`Uint8Array`、`Uint32Array`等)有一个通用术语是 [TypedArray](https://tc39.github.io/ecma262/#sec-typedarray-objects)。它们都享有同一组方法和属性。 +所有这些视图(`Uint8Array`, `Uint32Array` 等)有一个通用术语是 [TypedArray](https://tc39.github.io/ecma262/#sec-typedarray-objects). 它们都享有同一组方法和属性。 它们更像普通数组:有索引,可遍历。 -一个类型化数组(无论是 `Int8Array` 或 `Float64Array`),其构造器因参数类型而异。 +类型化数组的构造函数(无论是 `Int8Array` 或 `Float64Array`)各不相同,具体取决于参数类型。 有 5 种参数变量: @@ -90,11 +89,11 @@ new TypedArray(); 1. 如果给定的是 `ArrayBuffer` 参数,则在其上创建视图。我们已经用过该语法了。 - Optionally we can provide `byteOffset` to start from (0 by default) and the `length` (till the end of the buffer by default),then the view will cover only a part of the `buffer`. + 根据需要,我们可以给定起始位置 `byteOffset` (默认为 0)以及 `length`(默认至缓存区的末尾),这样视图就会只涵盖 `buffer` 的一部分。 -2. 如果给定的是 `Array`、或任何类似数组的对象,则创建一个相同长度的类型化数组,并复制其内容。 +2. 如果给定的是 `Array`、或任何类似数组的对象,则创建一个相同长度的类型化数组,并复制值。 - 我们可以通过此构造器用该数据来预填充数组: + 我们可以使用它来预填充数据: ```js run *!* let arr = new Uint8Array([0, 1, 2, 3]); @@ -109,25 +108,24 @@ new TypedArray(); let arr8 = new Uint8Array(arr16); */!* alert( arr8[0] ); // 1 - alert( arr8[1] ); // 232 (试图复制 1000,但无法将 1000 放进 8 位字节中。) + alert( arr8[1] ); // 232(试图复制 1000,但无法将 1000 放进 8 位字节中。) ``` -4. For a numeric argument `length` -- creates the typed array to contain that many elements. Its byte length will be `length` multiplied by the number of bytes in a single item `TypedArray.BYTES_PER_ELEMENT`: +4. 对于整型参数 `length` -- 创建包含 `length` 这么多元素的类型化数组。它的字节长度将是 `length` 乘以单个 `TypedArray.BYTES_PER_ELEMENT` 中的字节数: ```js run - let arr = new Uint16Array(4); // create typed array for 4 integers - alert( Uint16Array.BYTES_PER_ELEMENT ); // 2 bytes per integer - alert( arr.byteLength ); // 8 (size in bytes) + let arr = new Uint16Array(4); // 为 4 个整数创建类型化数组 + alert( Uint16Array.BYTES_PER_ELEMENT ); // 每个整数 2 个字节 + alert( arr.byteLength ); // 8 (大小,以字节为单位) ``` -5. Without arguments,creates an zero-length typed array. +5. 不带参数的情况下,创建零长度的类型化数组。 -We can create a `TypedArray` directly,without mentioning `ArrayBuffer`. But a view cannot exist without an underlying `ArrayBuffer`,so gets created automatically in all these cases except the first one (when provided). +我们可以直接创建一个 `TypedArray`,而无需提及 `ArrayBuffer`。但是,视图离不开底层的 `ArrayBuffer`,因此在所有这些情况下(第一个除外)都会自动创建 `ArrayBuffer`(如果提供的话)。 -To access the `ArrayBuffer`,there are properties: -- `arr.buffer` -- references the `ArrayBuffer`. -- `arr.byteLength` -- the length of the `ArrayBuffer`. +如要访问 `ArrayBuffer`,可以用以下属性:- `arr.buffer` -- 引用 `ArrayBuffer`。 +- `arr.byteLength` -- `ArrayBuffer` 的长度。 -因此,我们总是可以从一个视图移动到另一个视图: +因此,我们总是可以从一个视图转到另一个视图: ```js let arr8 = new Uint8Array([0, 1, 2, 3]); @@ -136,44 +134,44 @@ let arr16 = new Uint16Array(arr8.buffer); ``` -以下是类型化数组的列表: +下面是类型化数组的列表: -- `Uint8Array`、`Uint16Array`、`Uint32Array` -- 用于 8、16 和 32 位的整数。 - - `Uint8ClampedArray` -- 用于 8 位整数, "clamps" them on assignment (see below). -- `Int8Array`, `Int16Array`, `Int32Array` -- 用于有符号整数(可以是负数)。 +- `Uint8Array`, `Uint16Array`, `Uint32Array` -- 用于 8、16 和 32 位的整数。 + - `Uint8ClampedArray` -- 对于 8 位整数,在赋值时便"固定"其值(见下文)。 +- `Int8Array`, `Int16Array`, `Int32Array` -- 用于有符号整数(可以为负数)。 - `Float32Array`, `Float64Array` -- 用于 32 位和 64 位的有符号浮点数。 ```warn header="无 `int8` 或类似的单值类型" -请注意,尽管有这样的命名 `Int8Array`,在 JavaScript 中并没有像 `int`,或 `int8` 这样的单值。 +请注意,尽管有类似 `Int8Array` 这样的名称,JavaScript 中并没有像 `int`,或 `int8` 这样的单值类型。 -这在逻辑上也说得通,因为 `Int8Array` 不是这些单一值的数组,而其实是 `ArrayBuffer` 上的视图。 +这是合乎逻辑的,因为 `Int8Array` 不是这些单值的数组,而是 `ArrayBuffer`上的视图。 ``` ### 越界行为 -What if we attempt to write an out-of-bounds value into a typed array? There will be no error. But extra bits are cut-off. +如果我们尝试将越界值写入类型化数组会出现什么情况?不会报错。但是多余的位被截断。 -For instance, let's try to put 256 into `Uint8Array`. In binary form, 256 is `100000000` (9 bits), but `Uint8Array` only provides 8 bits per value, that makes the available range from 0 to 255. +例如,我们试着将 256 放入 `Uint8Array`。256 的二进制格式是 `100000000` (9 位),但 `Uint8Array` 每个值只有 8 位,因此可用范围为 0 到 255。 -For bigger numbers, only the rightmost (less significant) 8 bits are stored, and the rest is cut off: +对于更大的数字,仅存储最右边的(低位有效)8 位,其余部分被截断: ![](8bit-integer-256.svg) -So we'll get zero. +因此结果是 0。 -For 257, the binary form is `100000001` (9 bits), the rightmost 8 get stored, so we'll have `1` in the array: +257 的二进制格式是 `100000001` (9 位),最右边的 8 位会被存储,因此数组中会有 `1` : ![](8bit-integer-257.svg) -In other words, the number modulo 28 is saved. +换句话说,该数字对 2 取余8 被保存。 -Here's the demo: +示例如下: ```js run let uint8array = new Uint8Array(16); let num = 256; -alert(num.toString(2)); // 100000000(二进制表示形式) +alert(num.toString(2)); // 100000000(二进制表示) uint8array[0] = 256; uint8array[1] = 257; @@ -182,88 +180,88 @@ alert(uint8array[0]); // 0 alert(uint8array[1]); // 1 ``` -`Uint8ClampedArray` is special in this aspect, its behavior is different. It saves 255 for any number that is greater than 255, and 0 for any negative number. That behavior is useful for image processing. +`Uint8ClampedArray` 在这方面比较特殊,不太一样。对于大于 255 的任何数字,它将保存为 255;对于任何负数,它将保存为 0。这对于图像处理很有用。 ## TypedArray 方法 -`TypedArray` 有普通的 `Array` 方法, with notable exceptions. +`TypedArray` 有普通的 `Array` 方法,但有个明显的例外。 我们可以遍历(iterate)、`map`、`slice`、`find`、`reduce`等等。 -但有几件事却不能做: +但有几件事我们不能做: -- 无 `splice` -- 我们不能"删除"一个值,因为类型数组是缓存区上的视图,是固定的连续内存空间。我们能做的只是赋值 0。 +- 无 `splice` -- 我们不能"删除"一个值,因为类型化数组是缓存区上的视图,并且是固定的、连续的内存区域。我们所能做的就是分配一个零值。 - 无 `concat` 方法。 -另有其他两个方法: +还有两种其他方法: -- `arr.set(fromArr, [offset])` 从 `fromArr` 中复制所有元素到 `arr`,从起始位置 `offset`(默认为 0)开始。 -- `arr.subarray([begin, end])` creates a new view of the same type from `begin` to `end` (exclusive). That's similar to `slice` method (that's also supported), but doesn't copy anything -- just creates a new view, to operate on the given piece of data. +- `arr.set(fromArr, [offset])` 将 `fromArr` 中从 `offset`(默认为 0)开始的所有元素复制到 `arr`。 +- `arr.subarray([begin, end])` 创建一个从 `begin` 到 `end`(不包括)相同类型的新视图。这类似于 `slice` 方法(同样也支持),但是不复制任何内容 - 只是创建一个新视图,对给定的数据进行操作。 -有了这些方法,我们可以复制类型数组, mix them,从现有数组创建新数组,等等。 +有了这些方法,我们可以复制、混合类型化数组,从现有数组创建新数组,等等。 ## 数据视图(DataView) -[DataView](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView) is a special super-flexible "untyped" view over `ArrayBuffer`. It allows to access the data on any offset in any format. +[DataView](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/DataView) 在 `ArrayBuffer` 上层,是一种特殊的超灵活“无类型”视图。它允许以任何格式访问任何偏移量的数据。 -- 对于类型数组,构造器决定了其格式。整个数组应该是 uniform。第 i 个数字是 `arr[i]`。 -- 通过 `DataView`,我们用诸如 `.getUint8(i)` 或 `.getUint16(i)` 方法来访问数据。我们在调用方法的时候选择格式,而不是在构造的时候。 +- 对于类型数组,构造器决定了其格式。整个数组应该是统一的。第 i 个数字是 `arr[i]`。 +- 通过 `DataView`,我们可以使用 `.getUint8(i)` 或 `.getUint16(i)` 之类的方法访问数据。我们在调用方法的时候选择格式,而不是在构造的时候。 -语法为: +语法: ```js new DataView(buffer, [byteOffset], [byteLength]) ``` -- **`buffer`** -- 底层的 `ArrayBuffer`。与类型数组不同的是,`DataView` doesn't create a buffer on its own. 我们需要事先准备好。 +- **`buffer`** -- 底层的 `ArrayBuffer`. 与类型化数组不同,`DataView`不会自行创建缓存区。我们需要事先准备好。 - **`byteOffset`** -- 视图的起始字节位置(默认为 0)。 -- **`byteLength`** -- 视图的字节长度(默认至 `buffer` 的最末尾)。 +- **`byteLength`** -- 视图的字节长度(默认至 `buffer` 的末尾)。 -例如,我们从同一缓存区提取不同格式的数字: +例如,这里我们从同一缓存区中提取不同格式的数字: ```js run let buffer = new Uint8Array([255, 255, 255, 255]).buffer; let dataView = new DataView(buffer); -// get 8-bit number at offset 0 +// 在偏移量为 0 处获取 8 位数字 alert( dataView.getUint8(0) ); // 255 -// now get 16-bit number at offset 0, that's 2 bytes, both with max value -alert( dataView.getUint16(0) ); // 65535 (biggest 16-bit unsigned int) +// 现在在偏移量为 0 处获取 16 位数字,即 2 个字节,都取最大值 +alert( dataView.getUint16(0) ); // 65535(最大的 16 位无符号整数) -// get 32-bit number at offset 0 -alert( dataView.getUint32(0) ); // 4294967295 (biggest 32-bit unsigned int) +// 在偏移量为 0 处获取 32 位数字 +alert( dataView.getUint32(0) ); // 4294967295(最大的 32 位无符号整数) -dataView.setUint32(0, 0); // set 4-byte number to zero +dataView.setUint32(0, 0); // 将 4 个字节的数字设为 0 ``` -当我们在同一缓存区内存储混合格式的数据时,`DataView` 非常有用。例如,我们存储一个成对序列(16 位整数,32 位浮点数),用 `DataView` 来访问便很容易。 +当我们在同一缓存区内存储混合格式的数据时,`DataView` 非常有用。例如,我们存储一个成对序列(16 位整数,32 位浮点数)。用 `DataView` 来访问便很容易。 ## 总结 -`ArrayBuffer` 是核心对象,是对固定长度的连续内存空间的引用。 +`ArrayBuffer` 是核心对象,是对固定长度的连续内存区域的引用。 几乎任何对 `ArrayBuffer` 的操作,都需要一个视图。 - 它可以是 `TypedArray`: - - `Uint8Array`, `Uint16Array`, `Uint32Array` -- 用于 8、16 和 32 位无符号整数。 - - `Uint8ClampedArray` -- 用于 8 位整数, "clamps" them on assignment. - - `Int8Array`, `Int16Array`, `Int32Array` -- 用于有符号整数(可以是负数)。 + - `Uint8Array`, `Uint16Array`, `Uint32Array` -- 用于 8 位、16 位和 32 位无符号整数。 + - `Uint8ClampedArray` -- 用于 8 位整数,在赋值时便"固定"其值。 + - `Int8Array`, `Int16Array`, `Int32Array` -- 用于有符号整数(可以为负数)。 - `Float32Array`, `Float64Array` -- 用于 32 位和 64 位的有符号浮点数。 - 或 `DataView` -- 通过方法(methods)来指定格式的视图,例如,`getUint8(offset)`。 -大多数情况下,我们直接在类型数组上创建和操作,`ArrayBuffer` under cover, as a "common discriminator". 我们可以通过 `.buffer` 来访问它,以及根据需要创建另一个视图。 +在多数情况下,我们直接对类型化数组进行创建和操作,而将“ ArrayBuffer”作为“普通区分器”隐藏起来。我们可以通过 `.buffer` 来访问它,并在需要时创建另一个视图。 -另有其他两个术语: +还有另外两个术语: - `ArrayBufferView` 是所有这些视图的总称。 - `BufferSource` 是 `ArrayBuffer` 或 `ArrayBufferView` 的总称。 -这两个术语用于操作二进制数据的方法描述中。`BufferSource` 是最常用的术语,意为 "任何类型的二进制数据" -- `ArrayBuffer` 或其上的视图. +这两个术语用于二进制数据操作的方法描述中。`BufferSource` 是最常用的术语之一,因为它的意思是 "任何类型的二进制数据" -- `ArrayBuffer` 或其上的视图。 -以下是备忘录(cheatsheet): +这是一份备忘单: ![](arraybuffer-view-buffersource.svg) From aea3dcee9dafec96402f93b7779615c9357b1874 Mon Sep 17 00:00:00 2001 From: bemself Date: Wed, 20 Nov 2019 22:46:41 +0800 Subject: [PATCH 03/14] arraybuffer: minor update --- 4-binary/01-arraybuffer-binary-arrays/article.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/4-binary/01-arraybuffer-binary-arrays/article.md b/4-binary/01-arraybuffer-binary-arrays/article.md index bf413e8b18..117602accb 100644 --- a/4-binary/01-arraybuffer-binary-arrays/article.md +++ b/4-binary/01-arraybuffer-binary-arrays/article.md @@ -19,15 +19,16 @@ alert(buffer.byteLength); // 16 它会分配一个 16 字节的连续内存区域,并预先用 0 填充。 -```warn header ="`ArrayBuffer` 不是某种数组"让我们来澄清一个可能的误区。‎`ArrayBuffer` 与 `Array` 没有任何共同之处: +```warn header ="`ArrayBuffer` 不是某种数组" +让我们来澄清一个可能的误区。‎`ArrayBuffer` 与 `Array` 没有任何共同之处: - 它长度固定,无法增加或减少。 - 它正好占用了内存中那么多的空间。 - 如要访问单个字节,需要另一个"视图"对象,而不是 `buffer[index]`。 ``` -`ArrayBuffer` 是一个内存区域它里面存储了什么?无从判断。只是一个原始的字节序列。 +`ArrayBuffer` 是一个内存区域。它里面存储了什么?无从判断。只是一个原始的字节序列。 -**如要操作 `ArrayBuffer`,我们需要使用"视图"对象。 +**如要操作 `ArrayBuffer`,我们需要使用"视图"对象。** 视图对象本身并不存储任何元素。它是一副”眼镜“,透过它来解析存储在 `ArrayBuffer` 中的字节。 @@ -70,7 +71,7 @@ for(let num of view) { ## 类型化数组(TypedArray) -所有这些视图(`Uint8Array`, `Uint32Array` 等)有一个通用术语是 [TypedArray](https://tc39.github.io/ecma262/#sec-typedarray-objects). 它们都享有同一组方法和属性。 +所有这些视图(`Uint8Array`, `Uint32Array` 等)有一个通用术语是 [TypedArray](https://tc39.github.io/ecma262/#sec-typedarray-objects)。它们都享有同一组方法和属性。 它们更像普通数组:有索引,可遍历。 @@ -122,7 +123,8 @@ new TypedArray(); 我们可以直接创建一个 `TypedArray`,而无需提及 `ArrayBuffer`。但是,视图离不开底层的 `ArrayBuffer`,因此在所有这些情况下(第一个除外)都会自动创建 `ArrayBuffer`(如果提供的话)。 -如要访问 `ArrayBuffer`,可以用以下属性:- `arr.buffer` -- 引用 `ArrayBuffer`。 +如要访问 `ArrayBuffer`,可以用以下属性: +- `arr.buffer` -- 引用 `ArrayBuffer`。 - `arr.byteLength` -- `ArrayBuffer` 的长度。 因此,我们总是可以从一个视图转到另一个视图: From 853a9b60fd19182909db17098d200f7f2fe706d5 Mon Sep 17 00:00:00 2001 From: bemself Date: Wed, 20 Nov 2019 22:54:20 +0800 Subject: [PATCH 04/14] arraybuffer: update task md --- 4-binary/01-arraybuffer-binary-arrays/01-concat/task.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/4-binary/01-arraybuffer-binary-arrays/01-concat/task.md b/4-binary/01-arraybuffer-binary-arrays/01-concat/task.md index 5d85dfec7f..162898c036 100644 --- a/4-binary/01-arraybuffer-binary-arrays/01-concat/task.md +++ b/4-binary/01-arraybuffer-binary-arrays/01-concat/task.md @@ -1,4 +1,4 @@ -# 拼接类型化数组(Concatenate typed arrays) +# 拼接类型化数组(Concatenate typed arrays) 给定一个 `Uint8Array` 数组,请写一个函数 `concat(arrays)` ,将数组拼接成一个单一数组并返回。 From d3f39b2466673b8055dc62df537985b2a7d1a001 Mon Sep 17 00:00:00 2001 From: bemself Date: Wed, 20 Nov 2019 22:58:04 +0800 Subject: [PATCH 05/14] arraybuffer: add trans for solution js --- .../01-concat/_js.view/solution.js | 6 +++--- .../01-concat/_js.view/source.js | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/4-binary/01-arraybuffer-binary-arrays/01-concat/_js.view/solution.js b/4-binary/01-arraybuffer-binary-arrays/01-concat/_js.view/solution.js index 2f51384efb..0721aebb71 100644 --- a/4-binary/01-arraybuffer-binary-arrays/01-concat/_js.view/solution.js +++ b/4-binary/01-arraybuffer-binary-arrays/01-concat/_js.view/solution.js @@ -1,13 +1,13 @@ function concat(arrays) { - // sum of individual array lengths + // 单个数组长度求和 let totalLength = arrays.reduce((acc, value) => acc + value.length, 0); if (!arrays.length) return null; let result = new Uint8Array(totalLength); - // for each array - copy it over result - // next array is copied right after the previous one + // 对于每个数组 - 复制到 result + // 下一个数组在前一个后面复制 let length = 0; for(let array of arrays) { result.set(array, length); diff --git a/4-binary/01-arraybuffer-binary-arrays/01-concat/_js.view/source.js b/4-binary/01-arraybuffer-binary-arrays/01-concat/_js.view/source.js index e88b1a5379..5900065cba 100644 --- a/4-binary/01-arraybuffer-binary-arrays/01-concat/_js.view/source.js +++ b/4-binary/01-arraybuffer-binary-arrays/01-concat/_js.view/source.js @@ -1,5 +1,5 @@ function concat(arrays) { - // ...your code... + // ...您的代码... } let chunks = [ From ecfbed6891f6224d11f04fb212b45a5e89a7baa0 Mon Sep 17 00:00:00 2001 From: bemself Date: Sat, 30 Nov 2019 21:11:20 +0800 Subject: [PATCH 06/14] arraybuffer: update trans against review comments --- .../01-arraybuffer-binary-arrays/01-concat/_js.view/solution.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/4-binary/01-arraybuffer-binary-arrays/01-concat/_js.view/solution.js b/4-binary/01-arraybuffer-binary-arrays/01-concat/_js.view/solution.js index 0721aebb71..69d331de3f 100644 --- a/4-binary/01-arraybuffer-binary-arrays/01-concat/_js.view/solution.js +++ b/4-binary/01-arraybuffer-binary-arrays/01-concat/_js.view/solution.js @@ -1,5 +1,5 @@ function concat(arrays) { - // 单个数组长度求和 + // 每个数组长度求和 let totalLength = arrays.reduce((acc, value) => acc + value.length, 0); if (!arrays.length) return null; From 163a27eb73bab2e3b447450b9f7d39403ba2dce7 Mon Sep 17 00:00:00 2001 From: bemself Date: Mon, 2 Dec 2019 20:22:35 +0800 Subject: [PATCH 07/14] arraybuffer: update against review comments --- 4-binary/01-arraybuffer-binary-arrays/article.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/4-binary/01-arraybuffer-binary-arrays/article.md b/4-binary/01-arraybuffer-binary-arrays/article.md index 117602accb..b4075e13cc 100644 --- a/4-binary/01-arraybuffer-binary-arrays/article.md +++ b/4-binary/01-arraybuffer-binary-arrays/article.md @@ -90,7 +90,7 @@ new TypedArray(); 1. 如果给定的是 `ArrayBuffer` 参数,则在其上创建视图。我们已经用过该语法了。 - 根据需要,我们可以给定起始位置 `byteOffset` (默认为 0)以及 `length`(默认至缓存区的末尾),这样视图就会只涵盖 `buffer` 的一部分。 + 根据需要,我们可以给定起始位置 `byteOffset`(默认为 0)以及 `length`(默认至缓存区的末尾),这样视图就会只涵盖 `buffer` 的一部分。 2. 如果给定的是 `Array`、或任何类似数组的对象,则创建一个相同长度的类型化数组,并复制值。 @@ -115,17 +115,17 @@ new TypedArray(); 4. 对于整型参数 `length` -- 创建包含 `length` 这么多元素的类型化数组。它的字节长度将是 `length` 乘以单个 `TypedArray.BYTES_PER_ELEMENT` 中的字节数: ```js run let arr = new Uint16Array(4); // 为 4 个整数创建类型化数组 - alert( Uint16Array.BYTES_PER_ELEMENT ); // 每个整数 2 个字节 + alert( Uint16Array.BYTES_PER_ELEMENT ); // 每个整数 2 个字节 alert( arr.byteLength ); // 8 (大小,以字节为单位) ``` 5. 不带参数的情况下,创建零长度的类型化数组。 -我们可以直接创建一个 `TypedArray`,而无需提及 `ArrayBuffer`。但是,视图离不开底层的 `ArrayBuffer`,因此在所有这些情况下(第一个除外)都会自动创建 `ArrayBuffer`(如果提供的话)。 +我们可以直接创建一个 `TypedArray`,而无需提及 `ArrayBuffer`。但是,视图离不开底层的 `ArrayBuffer`,因此除第一种情况(已提供 `ArrayBuffer`)外,其他所有情况都会自动创建 `ArrayBuffer`。 如要访问 `ArrayBuffer`,可以用以下属性: - `arr.buffer` -- 引用 `ArrayBuffer`。 -- `arr.byteLength` -- `ArrayBuffer` 的长度。 +- `arr.byteLength` -- `ArrayBuffer` 的长度。 因此,我们总是可以从一个视图转到另一个视图: ```js @@ -198,7 +198,7 @@ alert(uint8array[1]); // 1 还有两种其他方法: - `arr.set(fromArr, [offset])` 将 `fromArr` 中从 `offset`(默认为 0)开始的所有元素复制到 `arr`。 -- `arr.subarray([begin, end])` 创建一个从 `begin` 到 `end`(不包括)相同类型的新视图。这类似于 `slice` 方法(同样也支持),但是不复制任何内容 - 只是创建一个新视图,对给定的数据进行操作。 +- `arr.subarray([begin, end])` 创建一个从 `begin` 到 `end`(不包括)相同类型的新视图。这类似于 `slice` 方法(同样也支持),但是不复制任何内容 -- 只是创建一个新视图,对给定的数据进行操作。 有了这些方法,我们可以复制、混合类型化数组,从现有数组创建新数组,等等。 From 95d667759f39dda0f850d1d04b6dc17c721fdfc2 Mon Sep 17 00:00:00 2001 From: bemself <45781328+bemself@users.noreply.github.com> Date: Wed, 4 Dec 2019 19:35:33 +0800 Subject: [PATCH 08/14] arraybuffer: resolve review comment resolve review comment Co-Authored-By: LeviDing --- .../01-arraybuffer-binary-arrays/01-concat/_js.view/solution.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/4-binary/01-arraybuffer-binary-arrays/01-concat/_js.view/solution.js b/4-binary/01-arraybuffer-binary-arrays/01-concat/_js.view/solution.js index 69d331de3f..91cc108428 100644 --- a/4-binary/01-arraybuffer-binary-arrays/01-concat/_js.view/solution.js +++ b/4-binary/01-arraybuffer-binary-arrays/01-concat/_js.view/solution.js @@ -1,5 +1,5 @@ function concat(arrays) { - // 每个数组长度求和 + // 对每个数组长度求和 let totalLength = arrays.reduce((acc, value) => acc + value.length, 0); if (!arrays.length) return null; From 73e1cbaab3c9a4a953ee51557139984115653593 Mon Sep 17 00:00:00 2001 From: bemself <45781328+bemself@users.noreply.github.com> Date: Wed, 4 Dec 2019 19:38:31 +0800 Subject: [PATCH 09/14] arraybuffer: resolve review comment Co-Authored-By: LeviDing --- 4-binary/01-arraybuffer-binary-arrays/01-concat/task.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/4-binary/01-arraybuffer-binary-arrays/01-concat/task.md b/4-binary/01-arraybuffer-binary-arrays/01-concat/task.md index 162898c036..164eb68719 100644 --- a/4-binary/01-arraybuffer-binary-arrays/01-concat/task.md +++ b/4-binary/01-arraybuffer-binary-arrays/01-concat/task.md @@ -1,4 +1,4 @@ # 拼接类型化数组(Concatenate typed arrays) -给定一个 `Uint8Array` 数组,请写一个函数 `concat(arrays)` ,将数组拼接成一个单一数组并返回。 +给定一个 `Uint8Array` 数组,请写一个函数 `concat(arrays)`,将数组拼接成一个单一数组并返回。 From fa9d61e0480f1a60b1e48bfab7994826e5e1c4e2 Mon Sep 17 00:00:00 2001 From: bemself <45781328+bemself@users.noreply.github.com> Date: Wed, 4 Dec 2019 19:38:59 +0800 Subject: [PATCH 10/14] arraybuffer: resolve review comment Co-Authored-By: LeviDing --- .../01-arraybuffer-binary-arrays/01-concat/_js.view/solution.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/4-binary/01-arraybuffer-binary-arrays/01-concat/_js.view/solution.js b/4-binary/01-arraybuffer-binary-arrays/01-concat/_js.view/solution.js index 91cc108428..123683ad7c 100644 --- a/4-binary/01-arraybuffer-binary-arrays/01-concat/_js.view/solution.js +++ b/4-binary/01-arraybuffer-binary-arrays/01-concat/_js.view/solution.js @@ -6,7 +6,7 @@ function concat(arrays) { let result = new Uint8Array(totalLength); - // 对于每个数组 - 复制到 result + // 对于每个数组 — 复制到 result // 下一个数组在前一个后面复制 let length = 0; for(let array of arrays) { From d823f7c711d5eb01e9c44ebceb42938b829265b6 Mon Sep 17 00:00:00 2001 From: bemself <45781328+bemself@users.noreply.github.com> Date: Wed, 4 Dec 2019 19:40:55 +0800 Subject: [PATCH 11/14] arraybuffer: resolve review comment Co-Authored-By: LeviDing --- 4-binary/01-arraybuffer-binary-arrays/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/4-binary/01-arraybuffer-binary-arrays/article.md b/4-binary/01-arraybuffer-binary-arrays/article.md index b4075e13cc..2176621aa7 100644 --- a/4-binary/01-arraybuffer-binary-arrays/article.md +++ b/4-binary/01-arraybuffer-binary-arrays/article.md @@ -5,7 +5,7 @@ JavaScript 中同样也会遇到,而且二进制操作性能也高。 不过,由于 JavaScript 中有很多类,会有点容易混淆。仅举几例: -- `ArrayBuffer`,`Uint8Array`,`DataView`,`Blob`,`File` 等。 +- `ArrayBuffer`、`Uint8Array`、`DataView`、`Blob` 和 `File` 等。 与其他语言相比,JavaScript 中二进制的实现方式不是很标准。但当我们理清楚以后,一切就变得相当简单了。 From 82ec646379ac0c8ce2ff4c7e47155decda41ec23 Mon Sep 17 00:00:00 2001 From: bemself <45781328+bemself@users.noreply.github.com> Date: Wed, 4 Dec 2019 19:41:53 +0800 Subject: [PATCH 12/14] arraybuffer: resolve review comment Co-Authored-By: LeviDing --- 4-binary/01-arraybuffer-binary-arrays/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/4-binary/01-arraybuffer-binary-arrays/article.md b/4-binary/01-arraybuffer-binary-arrays/article.md index 2176621aa7..c727779823 100644 --- a/4-binary/01-arraybuffer-binary-arrays/article.md +++ b/4-binary/01-arraybuffer-binary-arrays/article.md @@ -261,7 +261,7 @@ dataView.setUint32(0, 0); // 将 4 个字节的数字设为 0 - `ArrayBufferView` 是所有这些视图的总称。 - `BufferSource` 是 `ArrayBuffer` 或 `ArrayBufferView` 的总称。 -这两个术语用于二进制数据操作的方法描述中。`BufferSource` 是最常用的术语之一,因为它的意思是 "任何类型的二进制数据" -- `ArrayBuffer` 或其上的视图。 +这两个术语用于二进制数据操作的方法描述中。`BufferSource` 是最常用的术语之一,因为它的意思是“任何类型的二进制数据” — `ArrayBuffer` 或其上的视图。 这是一份备忘单: From 192760a3a1c4a25dbb9b80f79da9ce3728292a8b Mon Sep 17 00:00:00 2001 From: bemself Date: Wed, 4 Dec 2019 20:53:32 +0800 Subject: [PATCH 13/14] arraybuffer: update against review comments --- .../01-concat/_js.view/source.js | 2 +- .../01-arraybuffer-binary-arrays/article.md | 74 +++++++++---------- 2 files changed, 38 insertions(+), 38 deletions(-) diff --git a/4-binary/01-arraybuffer-binary-arrays/01-concat/_js.view/source.js b/4-binary/01-arraybuffer-binary-arrays/01-concat/_js.view/source.js index 5900065cba..3ca0544d03 100644 --- a/4-binary/01-arraybuffer-binary-arrays/01-concat/_js.view/source.js +++ b/4-binary/01-arraybuffer-binary-arrays/01-concat/_js.view/source.js @@ -1,5 +1,5 @@ function concat(arrays) { - // ...您的代码... + // ...你的代码... } let chunks = [ diff --git a/4-binary/01-arraybuffer-binary-arrays/article.md b/4-binary/01-arraybuffer-binary-arrays/article.md index c727779823..d7c2281ae6 100644 --- a/4-binary/01-arraybuffer-binary-arrays/article.md +++ b/4-binary/01-arraybuffer-binary-arrays/article.md @@ -9,7 +9,7 @@ JavaScript 中同样也会遇到,而且二进制操作性能也高。 与其他语言相比,JavaScript 中二进制的实现方式不是很标准。但当我们理清楚以后,一切就变得相当简单了。 -**基本的二进制对象是 `ArrayBuffer` -- 对固定长度的连续内存空间的引用。** +**基本的二进制对象是 `ArrayBuffer` — 对固定长度的连续内存空间的引用。** 我们如下创建一个 ArrayBuffer: ```js run @@ -19,27 +19,27 @@ alert(buffer.byteLength); // 16 它会分配一个 16 字节的连续内存区域,并预先用 0 填充。 -```warn header ="`ArrayBuffer` 不是某种数组" +```warn header="`ArrayBuffer` 不是某种数组" 让我们来澄清一个可能的误区。‎`ArrayBuffer` 与 `Array` 没有任何共同之处: - 它长度固定,无法增加或减少。 - 它正好占用了内存中那么多的空间。 -- 如要访问单个字节,需要另一个"视图"对象,而不是 `buffer[index]`。 +- 如要访问单个字节,需要另一个“视图”对象,而不是 `buffer[index]`。 ``` `ArrayBuffer` 是一个内存区域。它里面存储了什么?无从判断。只是一个原始的字节序列。 -**如要操作 `ArrayBuffer`,我们需要使用"视图"对象。** +**如要操作 `ArrayBuffer`,我们需要使用“视图”对象。** -视图对象本身并不存储任何元素。它是一副”眼镜“,透过它来解析存储在 `ArrayBuffer` 中的字节。 +视图对象本身并不存储任何元素。它是一副“眼镜”,透过它来解析存储在 `ArrayBuffer` 中的字节。 例如: -- **`Uint8Array`** -- 将 "ArrayBuffer" 中的每个字节视为 0 到 255 之间的单个数字(每个字节是 8 位,因此只能容纳那么多)。此类值称为 "8 位无符号整数"。 -- **`Uint16Array`** -- 将每 2 个字节视为一个 0 到 65535 的整数。此类值称为"16 位无符号整数"。 -- **`Uint32Array`** -- 将每 4 个字节视为一个 0 到 4294967295 之间的整数。此类值称为"32 位无符号整数"。 -- **`Float64Array`** -- 将每 8 个字节视为一个 5.0x10-3241.8x10308 之间的浮点数。 +- **`Uint8Array`** — 将 "ArrayBuffer" 中的每个字节视为 0 到 255 之间的单个数字(每个字节是 8 位,因此只能容纳那么多)。此类值称为“8 位无符号整数”。 +- **`Uint16Array`** — 将每 2 个字节视为一个 0 到 65535 的整数。此类值称为“16 位无符号整数”。 +- **`Uint32Array`** — 将每 4 个字节视为一个 0 到 4294967295 之间的整数。此类值称为“32 位无符号整数”。 +- **`Float64Array`** — 将每 8 个字节视为一个 5.0x10-3241.8x10308 之间的浮点数。 -因此,一个 16 字节 `ArrayBuffer` 中的二进制数据可以表示为 16 个"小数字",或 8 个较大的数字(每个数字 2 个字节),或 4 个更大的数字 (每个数字 4 个字节),或 2 个高精度的浮点数(每个数字 8 个字节)。 +因此,一个 16 字节 `ArrayBuffer` 中的二进制数据可以表示为 16 个“小数字”,或 8 个较大的数字(每个数字 2 个字节),或 4 个更大的数字(每个数字 4 个字节),或 2 个高精度的浮点数(每个数字 8 个字节)。 ![](arraybuffer-views.svg) @@ -64,14 +64,14 @@ view[0] = 123456; // 遍历值 for(let num of view) { - alert(num); // 123456,然后是 0,0,0 (一共 4 个值) + alert(num); // 123456,然后是 0,0,0(一共 4 个值) } ``` ## 类型化数组(TypedArray) -所有这些视图(`Uint8Array`, `Uint32Array` 等)有一个通用术语是 [TypedArray](https://tc39.github.io/ecma262/#sec-typedarray-objects)。它们都享有同一组方法和属性。 +所有这些视图(`Uint8Array`、`Uint32Array` 等)有一个通用术语是 [TypedArray](https://tc39.github.io/ecma262/#sec-typedarray-objects)。它们都享有同一组方法和属性。 它们更像普通数组:有索引,可遍历。 @@ -90,7 +90,7 @@ new TypedArray(); 1. 如果给定的是 `ArrayBuffer` 参数,则在其上创建视图。我们已经用过该语法了。 - 根据需要,我们可以给定起始位置 `byteOffset`(默认为 0)以及 `length`(默认至缓存区的末尾),这样视图就会只涵盖 `buffer` 的一部分。 + 根据需要,我们可以给定起始位置 `byteOffset`(默认为 0)以及 `length`(默认至缓存区的末尾),这样视图就会只涵盖 `buffer` 的一部分。 2. 如果给定的是 `Array`、或任何类似数组的对象,则创建一个相同长度的类型化数组,并复制值。 @@ -112,20 +112,20 @@ new TypedArray(); alert( arr8[1] ); // 232(试图复制 1000,但无法将 1000 放进 8 位字节中。) ``` -4. 对于整型参数 `length` -- 创建包含 `length` 这么多元素的类型化数组。它的字节长度将是 `length` 乘以单个 `TypedArray.BYTES_PER_ELEMENT` 中的字节数: +4. 对于整型参数 `length` — 创建包含 `length` 这么多元素的类型化数组。它的字节长度将是 `length` 乘以单个 `TypedArray.BYTES_PER_ELEMENT` 中的字节数: ```js run let arr = new Uint16Array(4); // 为 4 个整数创建类型化数组 alert( Uint16Array.BYTES_PER_ELEMENT ); // 每个整数 2 个字节 - alert( arr.byteLength ); // 8 (大小,以字节为单位) + alert( arr.byteLength ); // 8(大小,以字节为单位) ``` 5. 不带参数的情况下,创建零长度的类型化数组。 -我们可以直接创建一个 `TypedArray`,而无需提及 `ArrayBuffer`。但是,视图离不开底层的 `ArrayBuffer`,因此除第一种情况(已提供 `ArrayBuffer`)外,其他所有情况都会自动创建 `ArrayBuffer`。 +我们可以直接创建一个 `TypedArray`,而无需提及 `ArrayBuffer`。但是,视图离不开底层的 `ArrayBuffer`,因此在所有这些情况下(第一个除外)都会自动创建 `ArrayBuffer`(如果提供的话)。 如要访问 `ArrayBuffer`,可以用以下属性: -- `arr.buffer` -- 引用 `ArrayBuffer`。 -- `arr.byteLength` -- `ArrayBuffer` 的长度。 +- `arr.buffer` — 引用 `ArrayBuffer`。 +- `arr.byteLength` — `ArrayBuffer` 的长度。 因此,我们总是可以从一个视图转到另一个视图: ```js @@ -138,10 +138,10 @@ let arr16 = new Uint16Array(arr8.buffer); 下面是类型化数组的列表: -- `Uint8Array`, `Uint16Array`, `Uint32Array` -- 用于 8、16 和 32 位的整数。 - - `Uint8ClampedArray` -- 对于 8 位整数,在赋值时便"固定"其值(见下文)。 -- `Int8Array`, `Int16Array`, `Int32Array` -- 用于有符号整数(可以为负数)。 -- `Float32Array`, `Float64Array` -- 用于 32 位和 64 位的有符号浮点数。 +- `Uint8Array`,`Uint16Array`,`Uint32Array` — 用于 8、16 和 32 位的整数。 + - `Uint8ClampedArray` — 对于 8 位整数,在赋值时便“固定“其值(见下文)。 +- `Int8Array`,`Int16Array`,`Int32Array` — 用于有符号整数(可以为负数)。 +- `Float32Array`,`Float64Array` — 用于 32 位和 64 位的有符号浮点数。 ```warn header="无 `int8` 或类似的单值类型" 请注意,尽管有类似 `Int8Array` 这样的名称,JavaScript 中并没有像 `int`,或 `int8` 这样的单值类型。 @@ -153,7 +153,7 @@ let arr16 = new Uint16Array(arr8.buffer); 如果我们尝试将越界值写入类型化数组会出现什么情况?不会报错。但是多余的位被截断。 -例如,我们试着将 256 放入 `Uint8Array`。256 的二进制格式是 `100000000` (9 位),但 `Uint8Array` 每个值只有 8 位,因此可用范围为 0 到 255。 +例如,我们试着将 256 放入 `Uint8Array`。256 的二进制格式是 `100000000`(9 位),但 `Uint8Array` 每个值只有 8 位,因此可用范围为 0 到 255。 对于更大的数字,仅存储最右边的(低位有效)8 位,其余部分被截断: @@ -161,11 +161,11 @@ let arr16 = new Uint16Array(arr8.buffer); 因此结果是 0。 -257 的二进制格式是 `100000001` (9 位),最右边的 8 位会被存储,因此数组中会有 `1` : +257 的二进制格式是 `100000001`(9 位),最右边的 8 位会被存储,因此数组中会有 `1`: ![](8bit-integer-257.svg) -换句话说,该数字对 2 取余8 被保存。 +换句话说,保存的是该数字对 28 取模的结果。 示例如下: @@ -188,17 +188,17 @@ alert(uint8array[1]); // 1 `TypedArray` 有普通的 `Array` 方法,但有个明显的例外。 -我们可以遍历(iterate)、`map`、`slice`、`find`、`reduce`等等。 +我们可以遍历(iterate)、`map`、`slice`、`find` 和 `reduce`等等。 但有几件事我们不能做: -- 无 `splice` -- 我们不能"删除"一个值,因为类型化数组是缓存区上的视图,并且是固定的、连续的内存区域。我们所能做的就是分配一个零值。 +- 无 `splice` — 我们不能“删除”一个值,因为类型化数组是缓存区上的视图,并且是固定的、连续的内存区域。我们所能做的就是分配一个零值。 - 无 `concat` 方法。 还有两种其他方法: - `arr.set(fromArr, [offset])` 将 `fromArr` 中从 `offset`(默认为 0)开始的所有元素复制到 `arr`。 -- `arr.subarray([begin, end])` 创建一个从 `begin` 到 `end`(不包括)相同类型的新视图。这类似于 `slice` 方法(同样也支持),但是不复制任何内容 -- 只是创建一个新视图,对给定的数据进行操作。 +- `arr.subarray([begin, end])` 创建一个从 `begin` 到 `end`(不包括)相同类型的新视图。这类似于 `slice` 方法(同样也支持),但是不复制任何内容 - 只是创建一个新视图,对给定的数据进行操作。 有了这些方法,我们可以复制、混合类型化数组,从现有数组创建新数组,等等。 @@ -217,9 +217,9 @@ alert(uint8array[1]); // 1 new DataView(buffer, [byteOffset], [byteLength]) ``` -- **`buffer`** -- 底层的 `ArrayBuffer`. 与类型化数组不同,`DataView`不会自行创建缓存区。我们需要事先准备好。 -- **`byteOffset`** -- 视图的起始字节位置(默认为 0)。 -- **`byteLength`** -- 视图的字节长度(默认至 `buffer` 的末尾)。 +- **`buffer`** — 底层的 `ArrayBuffer`。与类型化数组不同,`DataView` 不会自行创建缓存区。我们需要事先准备好。 +- **`byteOffset`** — 视图的起始字节位置(默认为 0)。 +- **`byteLength`** — 视图的字节长度(默认至 `buffer` 的末尾)。 例如,这里我们从同一缓存区中提取不同格式的数字: @@ -249,13 +249,13 @@ dataView.setUint32(0, 0); // 将 4 个字节的数字设为 0 几乎任何对 `ArrayBuffer` 的操作,都需要一个视图。 - 它可以是 `TypedArray`: - - `Uint8Array`, `Uint16Array`, `Uint32Array` -- 用于 8 位、16 位和 32 位无符号整数。 - - `Uint8ClampedArray` -- 用于 8 位整数,在赋值时便"固定"其值。 - - `Int8Array`, `Int16Array`, `Int32Array` -- 用于有符号整数(可以为负数)。 - - `Float32Array`, `Float64Array` -- 用于 32 位和 64 位的有符号浮点数。 -- 或 `DataView` -- 通过方法(methods)来指定格式的视图,例如,`getUint8(offset)`。 + - `Uint8Array`,`Uint16Array`,`Uint32Array` — 用于 8 位、16 位和 32 位无符号整数。 + - `Uint8ClampedArray` — 用于 8 位整数,在赋值时便“固定”其值。 + - `Int8Array`,`Int16Array`,`Int32Array` — 用于有符号整数(可以为负数)。 + - `Float32Array`,`Float64Array` — 用于 32 位和 64 位的有符号浮点数。 +- 或 `DataView` — 通过方法(methods)来指定格式的视图,例如,`getUint8(offset)`。 -在多数情况下,我们直接对类型化数组进行创建和操作,而将“ ArrayBuffer”作为“普通区分器”隐藏起来。我们可以通过 `.buffer` 来访问它,并在需要时创建另一个视图。 +在多数情况下,我们直接对类型化数组进行创建和操作,而将 “ArrayBuffer” 作为“普通区分器”隐藏起来。我们可以通过 `.buffer` 来访问它,并在需要时创建另一个视图。 还有另外两个术语: - `ArrayBufferView` 是所有这些视图的总称。 From e2c0214f45ab93a63270dbd9ce87674b31b7dd0a Mon Sep 17 00:00:00 2001 From: bemself Date: Wed, 4 Dec 2019 22:54:10 +0800 Subject: [PATCH 14/14] arraybuffer: update against review comment --- .../01-arraybuffer-binary-arrays/01-concat/_js.view/source.js | 2 +- 4-binary/01-arraybuffer-binary-arrays/article.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/4-binary/01-arraybuffer-binary-arrays/01-concat/_js.view/source.js b/4-binary/01-arraybuffer-binary-arrays/01-concat/_js.view/source.js index 3ca0544d03..419055b5c4 100644 --- a/4-binary/01-arraybuffer-binary-arrays/01-concat/_js.view/source.js +++ b/4-binary/01-arraybuffer-binary-arrays/01-concat/_js.view/source.js @@ -1,5 +1,5 @@ function concat(arrays) { - // ...你的代码... + // ……你的代码…… } let chunks = [ diff --git a/4-binary/01-arraybuffer-binary-arrays/article.md b/4-binary/01-arraybuffer-binary-arrays/article.md index d7c2281ae6..e25e1716f8 100644 --- a/4-binary/01-arraybuffer-binary-arrays/article.md +++ b/4-binary/01-arraybuffer-binary-arrays/article.md @@ -165,7 +165,7 @@ let arr16 = new Uint16Array(arr8.buffer); ![](8bit-integer-257.svg) -换句话说,保存的是该数字对 28 取模的结果。 +换句话说,该数字对 28 取模的结果被保存了下来。 示例如下: