Javascript TypedArray 解惑:Uint8Array 与 Uint8ClampedArray 的区别

JS的类型数组大体可分为3类:无符号整数、有符号整数、浮点数。

Int8Array; Uint8Array; Uint8ClampedArray; Int16Array; Uint16Array; Int32Array; Uint32Array; Float32Array; Float64Array;

基本上都可以望文生义,看名字就知道怎么回事。

但是有一个例外 Uint8ClampedArray ,它与 Uint8Array 颇为相似,但又有所区别。

因为颜色数据刚好都是符合8位二进制的无符号整数,所以这两个类型在处理Canvas绘图数据时常常用到。

Uint8ClampedArray主要用于某些特殊场景,典型的就是 ImageData.

clamped这个词的字面意思是“紧固的,夹紧的”。

如果输入的值已经是0~255之间的整数,那么Uint8Array 与 Uint8ClampedArray的最终结果是一致的。

Uint8Array 与 Uint8ClampedArray 的区别,就在于处理不在该范围(0~255之间的整数)的输入数值的转换逻辑的差异。

Uint8Array采用的转换逻辑是ToUint8 .

其中一个关键点是,它将输入数与256取模,将8个比特位转化为正整数,它也不会进行四舍五入。

所以 new Uint8Array([33.999]) 等价于 new Uint8Array([33.111])

特别注意,对于负数来说,由于负数的二进制存储形式是补码形式的,其转换后得到的值与输入值的联系就不直观了。

例如 -23,二进制是11101001即得233 (23的二进制是00010111,它的补码就是11101001),

所以new Uint8Array([-23]) 等价于 new Uint8Array([233])

详细规则如下:

  1. Let number be ToNumber(argument).
  2. ReturnIfAbrupt(number).
  3. If number is NaN, +0, ?0, +∞, or ?∞, return +0.
  4. Let int be sign(number) × floor(abs(number)).
  5. Let int8bit be int modulo 28.
  6. Return int8bit.

Uint8ClampedArray 采用的转换逻辑是ToUint8Clamp

它会将负数归入0,大于255的数归入255,所以取模就不用了。

所以new Uint8ClampedArray([-23]) 等价于 new Uint8ClampedArray([
0 ])

上面说到 new Uint8Array([-23]) 等价于 new Uint8Array([ 233 ]) ,这样就看出差别了吧。

另外,它不是直接取整,而是会处理舍入,但并不是像Math.round()那样的四舍五入,而是采用一种叫做银行家舍入的方法。

详细规则如下:

  1. Let number be ToNumber(argument).
  2. ReturnIfAbrupt(number).
  3. If number is NaN, return +0.
  4. If number ≤ 0, return +0.
  5. If number ≥ 255, return 255.
  6. Let f be floor(number).
  7. If f + 0.5 < number, then return f + 1.
  8. If number < f + 0.5, then return f.
  9. If f is odd, then return f + 1.
  10. Return f.

参考

时间: 2025-01-07 10:17:44

Javascript TypedArray 解惑:Uint8Array 与 Uint8ClampedArray 的区别的相关文章

JavaScript中的property和attribute的区别

时间: 2013-09-06 | 10:24 作者: 玉面小飞鱼 分类: DOM, js相关, 前端技术 2,222 次浏览 1. 定义 Property:属性,所有的HTML元素都由HTMLElement类型表示,HTMLElement类型直接继承自Element并添加了一些属性,添加的这些属性分别对应于每个HTML元素都有下面的这5个标准特性: id,title,lang,dir,className.DOM节点是一个对象,因此,他可以和其他的JavaScript对象一样添加自定义的属性以及方

JavaScript中object和Object有什么区别

JavaScript中object和Object有什么区别,为什么用typeof检测对象,返回object,而用instanceof 必须要接Object呢 -------------------------------------------------------------------- 这个问题和我之前遇到的问题非常相似,我认为这里有两个问题需要解决,一个是运算符new的作用机制,一个是function关键字和Funtion内置对象之间的区别.看了一些前辈的博客和标准,这里帮提问者总结一

Javascript函数声明与函数表达式的区别

在定义函数时,我们一般使用下面这两种方法: 使用函数声明定义: 1 2 3 function  sum (a, b) {     return a + b; } 使用函数表达式定义: 1 2 3 var sum = function (a, b) {     return a + b; } 调用方法都是一样的: 如求"1+1"等于几: 1 alert(sum(1, 1)); 但这两种方法还是有区别的.解析器在向执行环境中加载数据时,对函数声明和函数表达式并非一视同仁.解析器会率先读取函

javascript 与 jquery 中的函数调用的区别

标签:例如<input id="btn_show" type="button" onclick="show()" /> <script type="text/javascript"> $(function(){ function show(){ -- } }) function show(){ -- } </script> 注意, 此时button的点击事件不会调用jquery中的show(

JavaScript学习笔记 isPrototypeOf和hasOwnProperty使用区别

1.isPrototypeOf isPrototypeOf是用来判断指定对象object1是否存在于另一个对象object2的原型链中,是则返回true,否则返回false. 格式如下: object1.isPrototypeOf(object2); object1是一个对象的实例: object2是另一个将要检查其原型链的对象. 原型链可以用来在同一个对象类型的不同实例之间共享功能. 如果 object2 的原型链中包含object1,那么 isPrototypeOf 方法返回 true. 如

【转】Javascript全局变量var与不var的区别

相信你对全局变量一定不陌生,在函数作用域里用a=1这种形式定义的变量会是一个全局变量,在全局作用域里,用下面3种形式都可以创建对全局可见的命名: 1 <script> 2 var a = 1; 3 b = 2; 4 window.c = 3; 5 </script> 对于b=2这种方式, 它其实和c是一样的,在执行这个赋值语句的时候,会沿着作用域链寻找名字叫做b的变量,一直找到作用域链的顶端还没有找到,于是给window添加一个属性b然后赋值. var与不var有两个区别: 1 v

Javascript添加事件的addEventListener()及attachEvent()区别分析

Mozilla中: addEventListener的使用方式: target.addEventListener(type, listener, useCapture); target: 文档节点.document.window 或 XMLHttpRequest. type: 字符串,事件名称,不含“on”,比如“click”.“mouseover”.“keydown”等. listener :实现了 EventListener 接口或者是 JavaScript 中的函数. useCapture

Javascript中的toString和valueOf的区别

语法:objectname.toString([radix])objectname要为其搜索字符串表示形式的对象.radix可选,为将数字值转换为字符串指定一个基数. 此值仅用于数字.toString 方法是一个所有内置的 JavaScript 对象的成员.它的行为取决于对象的类型: valueOf:返回指定对象的基元值. 语法:object.valueOf( )object 引用是任何内部 JavaScript 对象,将通过不同的方式为每个内部 JavaScript 对象定义 valueOf

javascript 函数声明和函数表达式的区别(学习笔记)

javascript中声明函数的方法有两种:函数声明式和函数表达式. 区别如下: 1).以函数声明的方法定义的函数,函数名是必须的,而函数表达式的函数名是可选的. 2).以函数声明的方法定义的函数,函数可以在函数声明之前调用,而函数表达式的函数只能在声明之后调用. 3).以函数声明的方法定义的函数并不是真正的声明,它们仅仅可以出现在全局中,或者嵌套在其他的函数中,但是它们不能出现在循环,条件或者try/catch/finally中,而 函数表达式可以在任何地方声明. 下面分别用两种方法定义函数: