奇怪的javascript运算符:expr >>> 0 [重复]

Posted

技术标签:

【中文标题】奇怪的javascript运算符:expr >>> 0 [重复]【英文标题】:Strange javascript operator: expr >>> 0 [duplicate] 【发布时间】:2011-08-10 11:12:15 【问题描述】:

以下函数旨在实现 IE 中的indexOf 属性。如果你曾经不得不这样做,我相信你以前见过。

if (!Array.prototype.indexOf)

  Array.prototype.indexOf = function(elt, from)

    var len = this.length >>> 0;
    var from = Number(arguments[1]) || 0;

    from = (from < 0)
         ? Math.ceil(from)
         : Math.floor(from);

    if (from < 0)
      from += len;

    for (; from < len; from++)
      if (from in this &&    
          this[from] === elt)
        return from;
    

    return -1;    
  ;

我想知道是否像作者在初始长度检查中所做的那样使用三个大于号?

var len = this.length &gt;&gt;&gt; 0

在控制台中执行此操作只会返回我传递给它的对象的长度,而不是 true 或 false,这让我思考语法的目的。这是一些我不知道的高级 javascript Ninja 技术吗?如果有,请赐教!

【问题讨论】:

【参考方案1】:

&gt;&gt;&gt; 是 Zero-fill right shift 运算符。 &gt;&gt;&gt; 0 滥用运算符将​​任何数字表达式转换为“整数”或将非数字表达式转换为零。它的作用如下:

此运算符将第一个操作数移动指定的位数 正确的。右移的多余位被丢弃。零 位从左侧移入。符号位变为 0,所以 结果总是积极的。

Here is an explanation 适用于所有按位运算的转换为整数行为:

按位运算符将其操作数视为 32 位序列(零 和一个),而不是十进制、十六进制或八进制数。 [...] 位运算符在此类二进制文件上执行操作 表示,但它们返回标准的 JavaScript 数值。

这些语句一起断言expr &gt;&gt;&gt; 0 将始终返回一个正数,如下所示:

    expr 被强制转换为 32 位整数以进行按位运算 &gt;&gt;&gt; 0 没有效果(没有位移) 结果转换为Number

以下是一些表达式及其结果:

        1 >>> 0 // 1 -- Number cast to 32-bit integer then back to Number
      "1" >>> 0 // 1 -- String cast to 32-bit integer then back to Number
undefined >>> 0 // 0 -- failed cast yields zero

其他有趣的案例:

      1.1 >>> 0 // 1          -- decimal portion gets it
       -1 >>> 0 // 4294967295 -- -1 = 0xFFFFFFFF
                //               Number(0xFFFFFFFF) = 4294967295
      "A" >>> 0 // 0          -- cast failed
    "1e2" >>> 0 // 100        -- 1x10^2 is 100
   "1e10" >>> 0 // 1410065408 -- 1x10^10 is 10000000000
                //               10000000000 is 0x00000002540BE400
                //               32 bits of that number is 0x540BE400
                //               Number(0x540BE400) is 1410065408

注意:您会注意到它们都没有返回NaN

【讨论】:

【参考方案2】:

来源:LINK

这是零填充右移 移位二进制的运算符 第一个操作数的表示 名额的权利 由第二个操作数指定。位 向右移动被丢弃 和零被添加到左边。 用正数你会得到 结果与 符号传播右移运算符, 但负数失去符号 像接下来一样变得积极 例如,其中(假设 'a' 是 -13) 将返回 1073741820:

代码:

result = a >>> b;

【讨论】:

哇,我是 waaaaay 了 :) 谢谢先生,我已经开悟了,你明白了。 那么var len = this.length &gt;&gt;&gt; 0这个例子中的用法到底有什么效果呢?这似乎无济于事。 如果你能推断出来,请分享!我认为这个问题最有趣的不是位移运算符的作用,而是为什么你可以用零作为操作数。 @jamietre:最终结果是任何值都将转换为数字。如果无法转换,则该数字将为 0。此外,任何小数位都将被删除。它类似于~~this.length。所以"123" &gt;&gt;&gt; 0 将是123,或者123.45 &gt;&gt;&gt; 0 将是123,或者"some unconvertable value" &gt;&gt;&gt; 0 将是0 我唯一可以假设的是,由于按位运算符通常非常快,因此考虑到最佳性能,它是这样做的。没有调用函数或执行布尔比较等任何开销。【参考方案3】:

&gt;&gt;&gt;(右移)二元运算符只是将数字的最右边的位移动指定次数,然后用零向左填充。

注意:在以下示例中,数字后面的大括号中的数字表示它的基数。2 表示二进制,10 表示十进制。

例如,4 &gt;&gt;&gt; 1 会这样做:

4(10) = 100(2)

4(10) >>> 1(10) = 010(2) = 2(10)
        shift once to the right

其他例子:

4(10) >>> 2(10) = 100(2) >>> 2(10) = 001(2) = 1(10)

10(10) >>> 4(10) = 1010(2) >>> 4(10) = 0000(2) = 0(10)

15(10) >>> 1(10) = 1111(2) >>> 1(10) = 0111(2) = 7

我记得的方法是将必要数量的位向右移动,然后写下数字。就像在上一个示例中,我只是将所有内容向右移动一次,所以结果是 0111。

移动 0 次不会……什么都没有。不知道为什么会在那里。

【讨论】:

非常好的回答先生! +1【参考方案4】:

看清零填充右移运算符。

https://developer.mozilla.org/en/JavaScript/Reference/Operators/Bitwise_Operators

【讨论】:

谢谢你,但你被打败了!为你 +1

以上是关于奇怪的javascript运算符:expr >>> 0 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

数学运算符

运算符优先级

具有两次以上递归的运算符优先级

Javascript赋值运算符奇怪的行为

let 与 expr Shell运算比较 let强强胜出

javascript 中函数eval()