1. 程式人生 > 程式設計 >JavaScript中各種二進位制物件關係的深入講解

JavaScript中各種二進位制物件關係的深入講解

目錄
  • 前言
  • 各種物件的關係
    • ArrayBuffer
    • TypedArray
      • Uint8ClampedArray
      • 字元的相互轉換
    • DataView
      • Blob
        • URL
        • 資料讀取
      • File
        • FileList
          • FileReader
          • 相關資料
            • 總結

              前言

              現代 要面臨更加複雜的場景,對於各種型別的資料傳輸也多了起來,其中涉及二進位制傳輸,為了方便處理資料提高效率於是創造了ArrayBuffer物件。

              但是使用中會發現不僅僅有ArrayBuffer,還有TypedArray、DataView、Blob、FileReader等一系列物件,讓人迷惑它們之間關係是什麼?為什麼有這麼多的物件?帶著問題查詢了資料,試著梳理其中的關係。

              各種物件的關係

              ArrayBuffer

              ArrayBuffer是 Script 最基本的處理二進位制的物件,描述的是一段連續的記憶體空間,其單位是位元組(byte)。

              const buffer = new ArrayBuffer(32);
              

              這樣我們就建立了一塊 32 位元組的記憶體區域,可以使用buffer.byteLength來檢視其長度。

              ArrayBuffer物件能做的操作不多,並且是不可編輯的。如果需要編輯資料,要利用另外兩個物件TypedArray與

              DataView。

              TypedArray

              TypedArray型別化陣列,TypedArray本www.cppcns.com身不儲存任何資料,只是專門用來檢視ArrayBuffer資料,所以稱之為,TypedArray不是某一個建構函式名,而是一組建構函式的統稱。

              • Int8Array:1 位元,8 位有符號整數
              • Uint8Array:1 位元,8 位無符號整數
              • Uint8ClampedArray:1 位元,8 位無符號整數
              • Int16Array:2 位元,16 位無符號整數
              • Uint16Array:2 位元,16 位無符號整數
              • Int32Array:4 位元,32 位無符號整數
              • Uint32Array:4 位元,32 位無符號整數
              • Float32Array:4 位元,32 位無 IEEE 浮點數
              • Float64Array:8 位元,64 位無 IEEE 浮點數
              • BigInt64Array:8 位元,64 http://www.cppcns.com
                為二進位制有符號整數
              • BigUint64Array:8 位元,64 位無符號整數

              建立的時候可以傳入長度、typedArray、ArrayBuffer、陣列。當然也可以什麼都不傳入。

              const uint1 = new Uint8Array(8);
              const uint2 = new Uint16Array(new Uint8Array(8));
              const uint3 = new Uint8Array(new ArrayBuffer(8));
              const uint4 = new Uint8Array([1,2,3]);
              const uint5 = new Uint8Array();
              

              以上typedArray中,除了建立時傳入ArrayBuffer不會新建立ArrayBuffer,其他在new過程中底層都會建立新的ArrayBuffer。可以使用arr.buffer來訪問其引用的ArrayBuffer。

              操作上普通陣列的操作都能在TypedArray 中使用。但因為ArrayBuffer描述的是連續的記憶體區間,所以我們無法刪除某一個值,只能分配為0,也沒辦法使用concat方法。

              Uint8ClampedArray

              Uint8ClampedArray相對特殊一點,在正負溢位的情況下處理不同。

              其他對於存入越界資料僅保留最右邊(低位)部分,拋棄溢位資料,而Uint8ClampedArray對越界資料都儲存為255,對於傳入的負數儲存為0。

              字元的相互轉換

              TypedArray不支出直接傳字串,所以需要先轉碼一下。

              String → Unit8Array

               const string = "Hello";
              Uint8Array.from(string.split(""),(e) => e.charCodeAt(0));
              

              Unit8Array → String

               // 使用TextDecoder物件
              const u8 = Uint8Array.of(72,101,108,111);
              new TextDecoder().decode(u8);
              // 使用fromCharCode轉換
              const u8 = Uint8Array.of(72,111);
              Array.from(u8,(e) => String.fromCharCode(e)).join("");
              

              DataView

              以上資料除了uint2變數,其他都是單一的資料型別,uint2物件這種一段記憶體中存放了兩種型別資料,稱之為複合檢視。JavaScript 中資料型別往往不那麼單一,僅用TypedArray操作會更加麻煩,所以又有了DataView物件。DataView相對於TypedArray有著更加多種的操作方法。

              const buffer = new ArrayBuffer(8);
              const dataView = new DataView(buffer);
              

              提供了getInt8、getUint8、getInt16、getUint16、getInt32、getUint32、getFloat32、getFloat64方法。

              引數有兩個,第一位是節序位置,第二位是位元組序,非必填。返回值是相應位置的位元組資料。

              const d1 = dataView.getUint8(1);
              const d2 = dataView.getUint8(1,true);
              

              位元組位置好理解,位元組序可以閱讀《理解位元組序》,總的說就是:

              • 大端位元組序(big endian):高位位元組在前,低位位元組在後,這是人類讀寫數值的方法。
              • 小端位元組序(little endian):低位位元組在前,高位位元組在後,即以 0x1122 形式儲存。

              預設情況下使用的是大端位元組序,如果要使用小端位元組序需要傳入true。

              這樣我們就有了基礎的二進位制的讀寫方案。可實際的應用場景中往往有更加複雜的資料,所以又針對專門的場景又衍生出Blob、FileReader等物件。

              Blob

              Blob,是Binary Large Object(二進位制大型物件)的縮寫。

              與ArrayBuffer差異是,ArrayBuffer是單純的二進位制資料,而Blob是帶MIME型別的二進位制資料。並且可以方便的從String、ArrayBuffer、TypedArray、DataView、Blob生成為Blob物件。

              const blob1 = new Blob(["hello"],{ type: "text/plain" });
              const blob2 = new Blob([new Uint8Array([72,111])," ","world"],{ type: "text/plain" });
              

              屬性:

              • size:讀取物件的位元組大小。
              • type:讀取寫入的MIME型別

              方法:

              • slice:提取Blob片段。

              URL

              在開發中我們獲取到圖片二進位制資料,我們可以轉換成base64寫入src中,但如果資料量很大,或者視訊資料,就會超過其允許長度。我們可以使用URL.createObjectURL來方便的建立一個資源的 URL。

              const url = URL.createObjectURL(blob1);
              

              會生成類似blob:https://example.com/a6728d20-2e78-4497-9d6c-0ed61b93f11e的資源 URL,可以直接寫入src中使用。

              在不用時使用URL.revokeObjectURL(url)銷燬其引用,釋放其記憶體佔用。

              資料讀取

              如果我們要檢視其中資料的話,有兩種方式。

              第一種,使用Response物件,可以直接讀取字串資料或是arrayBuffer資料。

              const responseText = await new Response(blob2).text();
              const responseBuf = await new Response(blob2).arrayBuffer();
              

              第二種,使用FileReader物件。

              const reader = new FileReader();
              reader.onload = function (e) {
                  console.log(reader.result);
              };
              reader.readAsText(blob2);
              

              File

              File繼承自Blob,並增加了檔案相關的屬性資訊。

              • name:檔名
              • lastModified:最後修改時間的時間戳
              • lastModifiedDate:最後修改時間的Date物件
              • webkitRelativePath:檔案的路徑。在 input 中選擇目錄時,會設定這個屬性,非標準特性。

              FileList

              FileList物件是File物件的集合。一般出現在:

              • <input type="file">控制元件,其中files屬性是一個FileList
              • 拖拽事件中產生的DataTransfer物件,其中files屬性會是一個FileList

              屬性:

              • length:可以獲取當前FileList包含多少個File

              方法:

              • item(index):可獲取指定索引位置的File資料,一般情況下直接使用FileList[index]替代了。

              FileReader

              FileReader在談Blob一節有提到過,實際上FileReader物件就是專門用來讀取Blob物件的,當然也包括擴充套件的File物件。

              屬性:

              • result:檔案的內容。
              • readyState:狀態。0:未載入;1:正在載入;2:載入完成。
              • error:載入資料時的錯誤資訊。

              事件:

              • onload:載入成功後觸發。
              • onerror:載入錯誤時觸發。
              • onabort:載入中斷時觸發。
              • onloadend:載入結束後觸發。
              • onloadstart:載入開始時觸發。
              • onprogress:載入中觸發。

              方法:

              • readAsText(blob,"uhttp://www.cppcns.comtf-8"):以文字形式返回資料,第二個引數可設定文字編碼。
              • readAsDataURL(blob):以Data URL的形式返回資料。
              • readAsArrayBuffer(blob):以ArrayBuffer形式返回資料。
              • abort:中止操作。

              如上面的示例,就是以文字形式返回資料:

              const reader = new FileReader();
              reader.onload = function (e) {
                  console.log(reader.result);
              };
              reader.readAsText(blob2);
              

              相關資料

              • MDN 相關的關鍵字
              • 現代 JavaScript 教程 第三部分 二進位制資料,檔案
              • 阮一峰 JavaScript 教程 瀏覽器模型相關章節

              總結

              到此這篇關於JavaScript中各種二進位制物件關係的文章就介紹到這了,更多相關二進位制物件關係內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!