最近在处理apng图像解码时,使用到Uint8Array
对象。发现该对象在部分android浏览器中没有slice
方法。
翻了一遍API文档,对象的slice
与subarray
方法字面描述基本一样。
于是使用subarray
方法取而代之。结果自然是很悲催了,解析出每帧数据都一样(解码过程中有去修改对象数据。)。
到这里大概已经猜到了subarray
与slice
的区别就在于内存空间占用上。
为探个究竟,跑个简单的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]
果然,修改b
,a
对应的值也是随之变化的,说明是在同一内存空间上。而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]
网友评论