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 取模的结果被保存了下来。 示例如下: pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy