diff options
| author | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:40:17 -0500 |
|---|---|---|
| committer | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:40:17 -0500 |
| commit | 33058f2b292b3a581333bdfb21b8f671898c5060 (patch) | |
| tree | 51c3e392513ec574331b2d3f85c394445ea803c6 /files/zh-cn/web/javascript/reference/global_objects/dataview/index.html | |
| parent | 8b66d724f7caf0157093fb09cfec8fbd0c6ad50a (diff) | |
| download | translated-content-33058f2b292b3a581333bdfb21b8f671898c5060.tar.gz translated-content-33058f2b292b3a581333bdfb21b8f671898c5060.tar.bz2 translated-content-33058f2b292b3a581333bdfb21b8f671898c5060.zip | |
initial commit
Diffstat (limited to 'files/zh-cn/web/javascript/reference/global_objects/dataview/index.html')
| -rw-r--r-- | files/zh-cn/web/javascript/reference/global_objects/dataview/index.html | 166 |
1 files changed, 166 insertions, 0 deletions
diff --git a/files/zh-cn/web/javascript/reference/global_objects/dataview/index.html b/files/zh-cn/web/javascript/reference/global_objects/dataview/index.html new file mode 100644 index 0000000000..7bd1755475 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/dataview/index.html @@ -0,0 +1,166 @@ +--- +title: DataView +slug: Web/JavaScript/Reference/Global_Objects/DataView +tags: + - DataView + - JavaScript + - TypedArrays + - 构造器 +translation_of: Web/JavaScript/Reference/Global_Objects/DataView +--- +<div>{{JSRef}}</div> + +<p><strong><code>DataView</code></strong> 视图是一个可以从 二进制{{jsxref("ArrayBuffer")}} 对象中读写多种数值类型的底层接口,使用它时,不用考虑不同平台的<a href="/zh-CN/docs/Glossary/Endianness">字节序</a>问题。</p> + +<div>{{EmbedInteractiveExample("pages/js/dataview-constructor.html")}}</div> + + + +<h2 id="语法">语法</h2> + +<pre class="syntaxbox">new DataView(<var>buffer</var> [, <var>byteOffset</var> [, <var>byteLength</var>]])</pre> + +<h3 id="参数">参数</h3> + +<dl> + <dt><code><var>buffer</var></code></dt> + <dd>一个 已经存在的{{jsxref("ArrayBuffer")}} 或 {{jsxref("SharedArrayBuffer")}} {{experimental_inline}} 对象,<code>DataView</code> 对象的数据源。</dd> + <dt><code><var>byteOffset</var></code> {{optional_inline}}</dt> + <dd>此 <code>DataView</code> 对象的第一个字节在 buffer 中的字节偏移。如果未指定,则默认从第一个字节开始。</dd> + <dt><code><var>byteLength</var></code> {{optional_inline}}</dt> + <dd>此 DataView 对象的字节长度。如果未指定,这个视图的长度将匹配buffer的长度。</dd> +</dl> + +<h3 id="返回值">返回值</h3> + +<p>一个表示指定数据缓存区的新<code>DataView</code> 对象。(这句话也许不是非常有助于说明清楚)</p> + +<p>你可以把返回的对象想象成一个二进制字节缓存区 array buffer 的“解释器”——它知道如何在读取或写入时正确地转换字节码。这意味着它能在二进制层面处理整数与浮点转化、字节顺序等其他有关的细节问题。</p> + +<h3 id="异常">异常</h3> + +<dl> + <dt><code>{{jsxref("RangeError")}}</code></dt> + <dd>如果 <code>byteOffset</code> 或者 <code>byteLength </code>参数的值导致视图超出了 buffer 的结束位置就会抛出此异常。<br> + 例如,假设 buffer (缓冲对象)是 16 字节长度,<code>byteOffset</code> 参数为 8,<code>byteLength</code> 参数为 10,这个错误就会抛出,这是因为结果视图试图超出 buffer 对象的总长度 2 个字节。</dd> +</dl> + +<h2 id="描述">描述</h2> + +<h3 id="Endianness(字节序)">Endianness(字节序)</h3> + +<p>需要多个字节来表示的数值,在存储时其字节在内存中的相对顺序依据平台架构的不同而不同,参照 {{Glossary("Endianness")}}。而使用 DataView 的访问函数时,不需要考虑平台架构中所使用的是哪种字节序。</p> + +<pre class="brush: js">var littleEndian = (function() { + var buffer = new ArrayBuffer(2); + new DataView(buffer).setInt16(0, 256, true /* 设置值时,使用小端字节序 */); + // Int16Array 使用系统字节序(由此可以判断系统字节序是否为小端字节序) + return new Int16Array(buffer)[0] === 256; +})(); +console.log(littleEndian); // 返回 true 或 false +</pre> + +<h3 id="64_位整数值">64 位整数值</h3> + +<p>因为 JavaScript 目前不包含对 64 位整数值支持的标准,所以 <code>DataView</code> 不提供原生的 64 位操作。作为变通,您可以实现自己的 <code>getUint64()</code> 函数,以获得精度高达 {{jsxref("Number.MAX_SAFE_INTEGER")}} 的值,可以满足某些特定情况的需求。</p> + +<pre class="brush: js">function getUint64(dataview, byteOffset, littleEndian) { + // 将 64 位整数值分成两份 32 位整数值 + const left = dataview.getUint32(byteOffset, littleEndian); + const right = dataview.getUint32(byteOffset+4, littleEndian); + + // 合并两个 32 位整数值 + const combined = littleEndian? left + 2**32*right : 2**32*left + right; + + if (!Number.isSafeInteger(combined)) + console.warn(combined, 'exceeds MAX_SAFE_INTEGER. Precision may be lost'); + + return combined; +} +</pre> + +<p>或者,如果需要填满 64 位,可以创建一个 {{jsxref("BigInt")}}。此外,尽管原生 BigInt 要比用户端的库中模拟的 BigInt 快得多,但在 JavaScript 中,BigInt 总是比 32 位整数慢得多,这是因为 BigInt 的大小是可变的。</p> + +<pre class="brush: js">const BigInt = window.BigInt, bigThirtyTwo = BigInt(32), bigZero = BigInt(0); +function getUint64BigInt(dataview, byteOffset, littleEndian) { + // 将 64 位整数值分成两份 32 位整数值 + const left = BigInt(dataview.getUint32(byteOffset|0, !!littleEndian)>>>0); + const right = BigInt(dataview.getUint32((byteOffset|0) + 4|0, !!littleEndian)>>>0); + + // 合并两个 32 位整数值并返回 + return littleEndian ? (right<<bigThirtyTwo)|left : (left<<bigThirtyTwo)|right; +}</pre> + +<h2 id="属性">属性</h2> + +<p>所有 <code>DataView</code> 实例都继承自 {{jsxref("DataView.prototype")}},并且允许向 DataView 对象中添加额外属性。</p> + +<div>{{page('zh-CN/Web/JavaScript/Reference/Global_Objects/DataView/prototype', '属性')}}</div> + +<h2 id="方法">方法</h2> + +<div>{{page('zh-CN/Web/JavaScript/Reference/Global_Objects/DataView/prototype', '方法')}}</div> + +<h2 id="示例">示例</h2> + +<pre class="brush: js">var buffer = new ArrayBuffer(16); +var view = new DataView(buffer, 0); + +view.setInt16(1, 42); +view.getInt16(1); // 42 +</pre> + +<h2 id="规范">规范</h2> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">规范名称</th> + <th scope="col">状态</th> + <th scope="col">注释</th> + </tr> + </thead> + <tbody> + <tr> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-dataview-constructor', 'DataView')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td></td> + </tr> + <tr> + <td>{{SpecName('ES6', '#sec-dataview-constructor', 'DataView')}}</td> + <td>{{Spec2('ES6')}}</td> + <td>ECMA 标准中的初始版本</td> + </tr> + <tr> + <td>{{SpecName('Typed Array')}}</td> + <td>{{Spec2('Typed Array')}}</td> + <td>Superseded by ECMAScript 6</td> + </tr> + </tbody> +</table> + +<h2 id="浏览器兼容性">浏览器兼容性</h2> + + + +<p>{{Compat("javascript.builtins.DataView")}}</p> + +<h2 id="兼容性提示">兼容性提示</h2> + +<p>从 FireFox 40 开始,DataView 对象需要通过 {{jsxref("Operators/new", "new")}} 操作符来构造。如果不使用 <code>new</code> 而是直接将 <code>DataView()</code> 作为函数调用的话,会抛出 {{jsxref("TypeError")}} 异常。</p> + +<pre class="brush: js example-bad">var dv = DataView(buffer, 0); +// 抛出异常,错误信息翻译为:禁止在不用 new 的情况下直接调用 DataView 的构造函数。 +// TypeError: calling a builtin DataView constructor without new is forbidden</pre> + +<pre class="brush: js example-good">var dv = new DataView(buffer, 0);</pre> + +<h2 id="请参阅">请参阅</h2> + +<ul> + <li><a class="link-https" href="https://github.com/jDataView/jDataView">jDataView</a>:DataView 的垫片(polyfill)库,使其能够用于所有浏览器及 Node.js 环境。同时,该库还对 DataView 进行了一些扩展。</li> + <li>{{jsxref("ArrayBuffer")}}</li> + <li>{{jsxref("SharedArrayBuffer")}}</li> +</ul> |
