zepto源码的Array.prototype.reduce有一行

len = t.length >>> 0

当时就很疑惑,知道 >>是移位,那>>>又是什么鬼,还有移位0位又有什么意义呢,带着强烈的好奇心,我就去探究了一下 >>> 0它到底暗藏什么玄机。

  • >> 和 >>>有什么不一样

查了MDN原来>>>是无符号右移,>>是有符号移位,
>>有符号移位:该操作符会将第一个操作数向右移动指定的位数。向右被移出的位被丢弃,拷贝最左侧的位以填充左侧

-9 >> 2
11111111111111111111111111110111 // -9 -> 11111111111111111111111111111101 // -3

>>>无符号移位:该操作符会将第一个操作数向右移动指定的位数。向右被移出的位被丢弃,左侧用0填充。因为符号位变成了 0,所以结果总是非负的。(即便右移 0 个比特,结果也是非负的。

9 >>> 2
00000000000000000000000000001001 // 9 -> 00000000000000000000000000000010 // 2

根据文档说明即使移动0位也可以将一个负数变成正数,甚至也可以将一个小数变成整数,将未定义的值转换为0,那到底移动0位是什么意思。

  • 移位0有什么意义

查过一些资料,其中stackoverflow里面有一个高票回答,里面有这么一句话

It doesn't just convert non-Numbers to Number, it converts them to Numbers that can be expressed as 32-bit unsigned ints.

原来移位操作符在移位前做了两种转换,第一将不是number类型的数据转换为number,第二将number转换为无符号的32bit数据,也就是Uint32类型。这些与移位的位数无关,移位0位主要就是用了js的内部特性做了前两种转换。

  • Uint32类型是如何转换的

1 . 如果不能转换为Number,那就为0
2 . 如果为非整数,先转换为整数,参考公式sign(n) ⋅ floor(abs(n))

function ToInteger(x) {
x = Number(x);
return x < 0 ? Math.ceil(x) : Math.floor(x);
}

3 . 如果是正数,返回正数,如果是负数,返回负数 + 2的32次方

function modulo(a, b) {
return a - Math.floor(a/b)*b;
}
function ToUint32(x) {
return modulo(ToInteger(x), Math.pow(2, 32));
}

------------------------------------------------------------------
// 3>>>0
// 3
// 3.5>>>0
// 3
// -3>>>0
// 4294967293
// 0>>>0
// 0
// null>>>0
// 0
// undefined>>>0
// 0
// '12'>>>0
// 12
// '-12'>>>0
// 4294967284

js中表达式 >>> 0 浅析的更多相关文章

  1. js中表达式 >>> 0 浅析 (以及用php简单翻译)

    今天在看lodash的源码中slice这个函数实现的时候发现了里面有这么一行代码 length = start > end ? 0 : ((end - start) >>> 0 ...

  2. js中的0就是false,非0就是true及案例

    在处理js代码判断真假时经常会这么写. 但fun()可能得到的是数字0,这可不是表示的没有值,但是!js中的数字0就是false,非0就是true. 于是0就被无情的当做false了. 已经被这个坑过 ...

  3. js中使用0 “” null undefined {}需要注意

    注意:在js中0为空(false) ,代表空的还有“”,null ,undefined: 如果做判断if(!上面的四种值):返回均为false console.log(!null);// true c ...

  4. js中的0就是false,非0就是true。

    在处理js代码判断真假时经常会这么写. var vale = fun();//从某个地方获取的值. if(!value){ 进入这里表示value为false或不存在 }但fun()可能得到的是数字0 ...

  5. JS中void(0)的含义

    看别人些的JavaScript脚本可以看到这样的代码: <a href="javascript:doTest2();void(0);">here</a> 但 ...

  6. JS中void(0)操作符的使用

    今天 在看源码时,发现这种写法 if(value === void(0)){ // } 以前没有见过这种写法,感觉就是判断一个变量是否有值,官网上是这样说的: void运算符 对给定的表达式进行求值, ...

  7. 如何更好的理解js中的this,分享2段有意思的代码

    关于js中this的浅析,大家可以点击[彻底理解js中this的指向,不必硬背]这篇博客了解. 今天遇到2段比较有意思的代码. ----------------第一段----------------- ...

  8. js中奇特的for循环写法

    //正常的for循环 for(var i=0;i<10;i++){ console.log(i); } //输出:1,2,3……10 //简写 for(var i=10;i--;){ conso ...

  9. js 中使用el表达式 关键总结:在js中使用el表达式一定要使用双引号

    js 中使用el表达式 关键总结:在js中使用el表达式一定要加双引号 js控制中用到了el表达式,最开始源码如下: var selected = ${requestScope.xxxxForm.re ...

随机推荐

  1. vue.js 官网及组件网站记录

    官网 https://cn.vuejs.org/v2/guide/ 饿了么组件: http://element-cn.eleme.io/#/zh-CN/component/tree 异步请求框架插件 ...

  2. P1553 数字反转(升级版)(模拟)

    花了2个小时,写的..mmp只想说,还是我太菜了. #include<iostream> #include<cstring> using namespace std; ]; i ...

  3. spring mybatis整合

    mybatis和spring整合的配置方法有很多,核心都是一个矛盾:如何让spring管理mybatis为mapper生成的代理对象. 1.配置数据源 单独使用mybatis的时候数据源是在mybat ...

  4. linux命令之vmstat

    vmstat 参数 功能:报告虚拟内存.swap.io.上下文和 CPU 统计信息. 分析了这些文件: /proc/meminfo /proc/stat /proc/*/stat 常用选项: -a 打 ...

  5. Emacs 中使用 shell

    直接在 Emacs 中使用 shell 能增加一点效率.Emacs 本身支持的 shell 相关的命令很多,此处化繁为简,只用一条足够了. M-x shell:将打开一个名为 * shell * 的 ...

  6. lintcode 515. Paint House

    Paint House 自己的写法: class Solution { public: /** * @param costs: n x 3 cost matrix * @return: An inte ...

  7. nginx+tomcat9+redisson+redis+jdk1.8简单实现session共享

    一.环境安装 由于资源限制,在虚拟机中模拟测试,一台虚拟机,所有软件均安装到该虚拟机内 安装系统:CentOS Linux release 7.4.1708 (Core) CentOS安装选择版本:B ...

  8. 深入理解 Node.js 中 EventEmitter源码分析(3.0.0版本)

    events模块对外提供了一个 EventEmitter 对象,即:events.EventEmitter. EventEmitter 是NodeJS的核心模块events中的类,用于对NodeJS中 ...

  9. Express+MongoDB开发web后台接口MongoDB

    摘要: Express开发web接口; 安装MongoDB,启动.连接MongoDB服务台; 使用nodejs和mongoose模块链接和操作MongoDB; 一.Express开发web接口 exp ...

  10. 深入理解[Master-Worker模式]原理与技术

    Master-Worker模式是常用的并行模式之一.它的核心思想是,系统由两类进程协作工作:Master进程和Worker进程.Master进程负责接收和分配任务,Worker进程负责处理子任务.当各 ...