목차
起源" >起源
构造函数" >构造函数
数据操作" >数据操作
数组类型" >数组类型
为什么要用TypedArray" >为什么要用TypedArray
参考文献" >参考文献
웹 프론트엔드 H5 튜토리얼 HTML5 中的新数组

HTML5 中的新数组

May 17, 2016 am 09:08 AM

Javascript中的数组是个强大的家伙:

  • 你可以创建的时候不规定长度,而是动态的去改变长度。
  • 你可以把他当成普通的数组去读取,也可以当他是堆栈来使用。
  • 你可以改变数组中每个元素的值甚至是类型。

好吧,其实他是一个对象,比如我们可以这样去创建数组:

<font size="3">var array = new Array(10);</font>
로그인 후 복사

Javascript的数组的强大以及全能,给我们带来了便捷性。但一般而言:

全能的东西能在各种环境下使用,但却不一定适用于各种环境。

而TypedArray正是为了解决Javascript中数组“干太多事”而出现的。

 

起源

TypedArray是一种通用的固定长度缓冲区类型,允许读取缓冲区中的二进制数据。

其在WEBGL规范中被引入用于解决Javascript处理二进制数据的问题。

TypedArray已经被大部分现代浏览器支持,例如可以用下面方法创建TypedArray:


<font size="3">    // 创建一个8-byte的ArrayBuffer
    var b = new ArrayBuffer(8);

    // 创建一个b的引用,类型是Int32,起始位置在0,结束位置为缓冲区尾部
    var v1 = new Int32Array(b);

    // 创建一个b的引用,类型是Uint8,起始位置在2,结束位置为缓冲区尾部
    var v2 = new Uint8Array(b, 2);

    // 创建一个b的引用,类型是Int16,起始位置在2,总长度为2
    var v3 = new Int16Array(b, 2, 2);</font>
로그인 후 복사

则缓冲和创建的引用布局为:

变量 索引
  字节数
b = 0 1 2 3 4 5 6 7
  索引数
v1 = 0 1
v2 =   0 1 2 3 4 5
v3 =   0 1  

这表示Int32类型的v1数组的第0个元素是ArrayBuffer类型的b的第0-3个字节,如此等等。

 

构造函数

上面我们通过ArrayBuffer来创建TypedArray,而实际上,TypedArray提供了3个构造函数来创建他的实例。

构造函数
TypedArray(unsigned long length)
创建一个新的TypedArray,length是其固定长度。
TypedArray(TypedArray array)
TypedArray(type[] array)
创建一个新的TypedArray,其每个元素根据array进行初始化,元素进行了相应的类型转换。
TypedArray(ArrayBuffer buffer, optional unsigned long byteOffset, optional unsigned long length)
创建一个新的TypedArray,使其作为buffer的一个引用,byteOffset为其起始的偏移量,length为其长度。

所以通常我们用下面的方式创建TypedArray:

<font size="3">var array = new Uint8Array(10);</font>
로그인 후 복사

或者:

<font size="3">var array = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);</font>
로그인 후 복사

 

数据操作

TypedArray提供了setter、getter、set和subarray四个方法进行数据操作。

方法
getter type get(unsigned long index)

返回指定索引的元素。

setter void set(unsigned long index, type value)

设置指定索引的元素为指定值。

void set(TypedArray array, optional unsigned long offset)
void set(type[] array, optional unsigned long offset)

根据array设置值,offset为偏移位置。

TypedArray subarray(long begin, optional long end)

返回一个新的TypedArray,起始位为begin,结束位为end。

例如读取元素可以用:

<font size="3">var array = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
alert(array[4]);    //5</font>
로그인 후 복사

设置元素可以用:

<font size="3">var array = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
alert(array[4]);    //5
array[4] = 12;
alert(array[4]);    //12</font>
로그인 후 복사

获取一个副本可以用:

<font size="3">var array = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
var array2 = array.subarray(0);</font>
로그인 후 복사

 

数组类型

类型 大小 描述 Web IDL类型 C 类型
Int8Array 1 8位有符号整数 byte signed char
Uint8Array 1 8位无符号整数 octet unsigned char
Uint8ClampedArray 1 8位无符号整数 (clamped) octet unsigned char
Int16Array 2 16位有符号整数 short short
Uint16Array 2 16位无符号整数 unsigned short unsigned short
Int32Array 4 32位有符号整数 long int
Uint32Array 4 32位无符号整数 unsigned long unsigned int
Float32Array 4 32位IEEE浮点数 unrestricted float float
Float64Array 8 64位IEEE浮点数 unrestricted double double

玩过canvas的可能会觉得很眼熟。

因为ImageData中用于存储图像数据的数组便是Uint8ClampedArray类型的。

例如:

<font size="3">var context = document.createElement("canvas").getContext("2d");

var imageData = context.createImageData(100, 100);

console.log(imageData.data);</font>
로그인 후 복사

其在FireBug中显示为:

Uint8ClampedArray { 0=0, 1=0, 2=0, 更多...}

 

为什么要用TypedArray

我们知道Javascript中数字是64位浮点数。则对于一个二进制图片(图片每个像素点是以8位无符号整数存储的),如果要将其数据在Javascript数组中使用,相当于使用了图片8倍的内存来存储一个图片的数据,这显然是不科学的。而TypedArray能帮助我们只使用原来1/8的内存来存储图片数据。

或者对于WebSocket,如果用base64进行传输也是一个花费较高的方式,转而使用二进制传送可能是更好的方式。

当然,TypedArray还有更多好处,比如具有更好的性能,下面我们进行一些小测试来验证这一点。

参与测试的浏览器为:

FireFox 17.0.1 和 Chrome 23.0.1271.97m

  • Test1:顺序读取速读

<font size="3">var timeArray1 = [];
var timeArray2 = [];

function check1(){
    var array = new Uint8ClampedArray(5000000);
    for(var i = array.length; i--;){
        array[i] = Math.floor(Math.random() * 100);
    }
    var temp;
    var time1 = (new Date()).getTime();
    for(var i = array.length; i--;){
        temp = array[i];
    }
    var time2 = (new Date()).getTime();
    console.log(time2 - time1);
    timeArray1.push(time2 - time1);
}

function check2(){
    var array2 = new Array(5000000);
    for(var i = array2.length; i--;){
        array2[i] = Math.floor(Math.random() * 100);
    }
    var temp;
    var time3 = (new Date()).getTime();
    for(var i = array2.length; i--;){
        temp = array2[i];
    }
    var time4 = (new Date()).getTime();
    console.log(time4 - time3);
    timeArray2.push(time4 - time3);
}

function timer(__fun, __time, __callback){
    var now = 0;
    function begin(){
        var timeout = setTimeout(function(){
            if(now !== __time){
                now++;
                __fun();
                begin();
            }else{
                if(timeArray1.length && timeArray2.length){
                    console.log("timeArray1 == " + timeArray1 + ", average == " + average(timeArray1));
                    console.log("timeArray2 == " + timeArray2 + ", average == " + average(timeArray2));
                }
                __callback && __callback();
            }
        }, 100);
    }
    begin();
}

function average(__array){
    var total = 0;
    for(var i = __array.length; i--;){
        total += __array[i];
    }
    return (total / __array.length);
}

timer(check1, 10, function(){
    timer(check2, 10);
});</font>
로그인 후 복사

HTML5 中的新数组

可见Uint8ClampedArray的读取速度明显比Array要快(条状柱越长,代表花费时间越多)。

  • Test2:随机读取

<font size="3">//……

function check1(){
    var array = new Uint8ClampedArray(5000000);
    for(var i = array.length; i--;){
        array[i] = Math.floor(Math.random() * 100);
    }
    var temp;
    var time1 = (new Date()).getTime();
    for(var i = array.length; i--;){
        temp = array[Math.floor(Math.random() * 5000000)];
    }
    var time2 = (new Date()).getTime();
    console.log(time2 - time1);
    timeArray1.push(time2 - time1);
}

function check2(){
    var array2 = new Array(5000000);
    for(var i = array2.length; i--;){
        array2[i] = Math.floor(Math.random() * 100);
    }
    var temp;
    var time3 = (new Date()).getTime();
    for(var i = array2.length; i--;){
        temp = array2[Math.floor(Math.random() * 5000000)];
    }
    var time4 = (new Date()).getTime();
    console.log(time4 - time3);
    timeArray2.push(time4 - time3);
}

//……</font>
로그인 후 복사

HTML5 中的新数组

随即读取中Uint8ClampedArray的读取速度也是比Array要快的。

  • Test3:顺序写入

<font size="3">//……

function check1(){
    var array = new Uint8ClampedArray(5000000);
    var time1 = (new Date()).getTime();
    for(var i = array.length; i--;){
        array[i] = Math.floor(Math.random() * 100);
    }
    var time2 = (new Date()).getTime();
    console.log(time2 - time1);
    timeArray1.push(time2 - time1);
}

function check2(){
    var array2 = new Array(5000000);
    var time3 = (new Date()).getTime();
    for(var i = array2.length; i--;){
        array2[i] = Math.floor(Math.random() * 100);
    }
    var time4 = (new Date()).getTime();
    console.log(time4 - time3);
    timeArray2.push(time4 - time3);
}

//……</font>
로그인 후 복사

HTML5 中的新数组

  • Test4:复制操作(U8C to U8C 和 Array to U8C)

<font size="3">//……

function check1(){
    var array = new Uint8ClampedArray(5000000);
    for(var i = array.length; i--;){
        array[i] = Math.floor(Math.random() * 100);
    }
    var temp;
    var array2 = new Uint8ClampedArray(5000000);
    var time1 = (new Date()).getTime();
    array2.set(array);
    var time2 = (new Date()).getTime();
    console.log(time2 - time1);
    timeArray2.push(time2 - time1);
}

function check2(){
    var array = new Array(5000000);
    for(var i = array.length; i--;){
        array[i] = Math.floor(Math.random() * 100);
    }
    var temp;
    var array2 = new Uint8ClampedArray(5000000);
    var time1 = (new Date()).getTime();
    array2.set(array);
    var time2 = (new Date()).getTime();
    console.log(time2 - time1);
    timeArray2.push(time2 - time1);
}

//……</font>
로그인 후 복사

HTML5 中的新数组

可见U8C复制到U8C,比Array复制到U8C快得多。

 

参考文献

Typed Array Specification

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

내 HTML5 웹 사이트에 오디오를 추가하는 방법은 무엇입니까? 내 HTML5 웹 사이트에 오디오를 추가하는 방법은 무엇입니까? Mar 10, 2025 pm 03:01 PM

이 기사는 & lt; audio & gt를 사용하여 HTML5에 오디오를 포함시키는 방법을 설명합니다. 형식 선택에 대한 모범 사례 (MP3, OGG Vorbis), 파일 최적화 및 재생에 대한 JavaScript 컨트롤을 포함한 요소. 다중 오디오를 사용하는 것을 강조합니다

Geolocation API로 사용자 위치 개인 정보 및 권한을 어떻게 처리합니까? Geolocation API로 사용자 위치 개인 정보 및 권한을 어떻게 처리합니까? Mar 18, 2025 pm 02:16 PM

이 기사는 지리적 위치 API를 사용하여 사용자 위치 개인 정보 및 권한 관리, 권한 요청, 데이터 보안 보장 및 개인 정보 보호법 준수에 대한 모범 사례를 강조하는 것에 대해 설명합니다.

사용자 입력에 HTML5 양식을 사용하는 방법은 무엇입니까? 사용자 입력에 HTML5 양식을 사용하는 방법은 무엇입니까? Mar 10, 2025 pm 02:59 PM

이 기사에서는 HTML5 양식을 작성하고 검증하는 방법을 설명합니다. 그것은 & lt; form & gt; 요소, 입력 유형 (텍스트, 이메일, 번호 등) 및 속성 (필수, 패턴, 최소, 최대). HTML5의 장점은 오래된 방법에 비해 형성됩니다

HTML5 페이지 가시성 API를 사용하여 페이지가 표시되는시기를 감지하려면 어떻게합니까? HTML5 페이지 가시성 API를 사용하여 페이지가 표시되는시기를 감지하려면 어떻게합니까? Mar 13, 2025 pm 07:51 PM

이 기사에서는 HTML5 페이지 가시성 API를 사용하여 페이지 가시성을 감지하고 사용자 경험을 향상 시키며 리소스 사용량을 최적화하는 것에 대해 설명합니다. 주요 측면에는 미디어 일시 정지, CPU 부하 감소 및 가시성 변경에 기반한 분석 관리가 포함됩니다.

뷰포트 메타 태그를 사용하여 모바일 장치에서 페이지 스케일링을 제어하려면 어떻게합니까? 뷰포트 메타 태그를 사용하여 모바일 장치에서 페이지 스케일링을 제어하려면 어떻게합니까? Mar 13, 2025 pm 08:00 PM

이 기사에서는 Viewport Meta 태그를 사용하여 모바일 장치의 페이지 스케일링을 제어하여 폭과 최적의 응답 성 및 성능을위한 초기 스케일과 같은 설정에 중점을 둡니다. character count : 159

HTML5 및 JavaScript로 대화 형 게임을 만드는 방법은 무엇입니까? HTML5 및 JavaScript로 대화 형 게임을 만드는 방법은 무엇입니까? Mar 10, 2025 pm 06:34 PM

이 기사는 JavaScript를 사용하여 대화식 HTML5 게임을 만드는 자세한 내용입니다. 게임 디자인, HTML 구조, CSS 스타일, JavaScript 로직 (이벤트 처리 및 애니메이션 포함) 및 오디오 통합을 다룹니다. 필수 JavaScript 라이브러리 (Phaser, PI

대화식 사용자 인터페이스에 HTML5 드래그 앤 드롭 API를 어떻게 사용합니까? 대화식 사용자 인터페이스에 HTML5 드래그 앤 드롭 API를 어떻게 사용합니까? Mar 18, 2025 pm 02:17 PM

이 기사는 HTML5 드래그 앤 드롭 API를 사용하여 대화식 사용자 인터페이스를 생성하고 요소를 드래그 가능하게 만들고 주요 이벤트를 처리하며 사용자 정의 피드백으로 사용자 경험을 향상시키는 방법을 자세히 설명합니다. 또한 일반적인 함정에 대해 설명합니다

클라이언트와 서버 간의 양방향 통신에 HTML5 WebSockets API를 어떻게 사용합니까? 클라이언트와 서버 간의 양방향 통신에 HTML5 WebSockets API를 어떻게 사용합니까? Mar 12, 2025 pm 03:20 PM

이 기사에서는 실시간, 양방향 클라이언트 서버 커뮤니케이션을위한 HTML5 WebSockets API를 설명합니다. 클라이언트 측 (JavaScript) 및 서버 측 (Python/Flask) 구현에 대해 자세히 설명하여 확장 성, 상태 관리,

See all articles