浅析Uint8Array.slice与Uint8Array.subarray

最近在处理apng图像解码时,使用到Uint8Array对象。发现该对象在部分android浏览器中没有slice方法。

翻了一遍API文档,对象的slicesubarray方法字面描述基本一样。

于是使用subarray方法取而代之。结果自然是很悲催了,解析出每帧数据都一样(解码过程中有去修改对象数据。)。

到这里大概已经猜到了subarrayslice的区别就在于内存空间占用上。

为探个究竟,跑个简单的demo来验证下:

let a = new Uint8Array([1,2,3,4,5,6]);

let b = a.subarray(3,5);
let c = a.slice(3,5);

// 将b的第一个值改为9
b[0] = 9;

console.log('a',a);
// 输出:a Uint8Array(6) [1, 2, 3, 9, 5, 6]

console.log('b',b);
// 输出:b Uint8Array(2) [9, 5]

console.log('c',c);
// 输出:c Uint8Array(2) [4, 5]

果然,修改ba对应的值也是随之变化的,说明是在同一内存空间上。而c不与前者内存共享,是在独立的空间上。

问题是找到了,解决办法就自然简单了。

方法有无数种。检查原型是否有对应的方法肯定是必不可少的。
如果原型上没有slice就自行往原型上添加一个即可。
方法有无数种(循环效率较低,这里还是决定使用原型本身的subarray来处理)。

最后解决问题的兼容代码如下:

// 兼容代码,如果原型上无`slice`则添加一个
if(!Uint8Array.prototype.slice){
    Uint8Array.prototype.slice = function(...arg){
        return new Uint8Array(this).subarray(...arg);
    }
};

let a = new Uint8Array([1,2,3,4,5,6]);
let b = b.slice(3,5);

console.log('a',a);
// 输出:a Uint8Array(6) [1, 2, 3, 4, 5, 6]

console.log('b',b);
// 输出:b Uint8Array(2) [4, 5]

你可能感兴趣的:(浅析Uint8Array.slice与Uint8Array.subarray)