Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/392.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
什么是JavaScript>&燃气轮机&燃气轮机;操作员和您如何使用它?_Javascript_Operators_Bit Shift - Fatal编程技术网

什么是JavaScript>&燃气轮机&燃气轮机;操作员和您如何使用它?

什么是JavaScript>&燃气轮机&燃气轮机;操作员和您如何使用它?,javascript,operators,bit-shift,Javascript,Operators,Bit Shift,我在看Mozilla的代码,它在数组中添加了一个过滤方法,它有一行代码让我感到困惑 var len = this.length >>> 0; 我以前从未见过在JavaScript中使用>>>它是什么,它做什么?那是操作员。这与之间的区别在于,无符号的右位移位运算符(>)从左开始填充零,有符号的右位移位运算符(>)填充符号位,因此,移位时保留数值的符号。充分解释了运算符是什么及其作用。下面是它背后的含义/使用原因: 按0移动任何方向都会返回原始数字,并将null转换为0。您正在

我在看Mozilla的代码,它在数组中添加了一个过滤方法,它有一行代码让我感到困惑

var len = this.length >>> 0;
我以前从未见过在JavaScript中使用>>>
它是什么,它做什么?

那是操作员。这与之间的区别在于,无符号的右位移位运算符(>)从左开始填充零,有符号的右位移位运算符(>)填充符号位,因此,移位时保留数值的符号。

充分解释了运算符是什么及其作用。下面是它背后的含义/使用原因:

0
移动任何方向都会返回原始数字,并将
null
转换为
0
。您正在查看的示例代码似乎是使用
this.length>>0
来确保
len
是数字的,即使未定义
this.length

对许多人来说,按位操作是不清楚的(道格拉斯·克罗克福德/jslint建议不要使用这种东西)。这并不意味着这样做是错误的,但存在更有利和更熟悉的方法来提高代码的可读性。确保
len
0
的更明确方法是以下两种方法之一

// Cast this.length to a number
var len = +this.length;


它不仅将非数字转换为数字,还将它们转换为可以表示为32位无符号整数的数字

尽管JavaScript的数字是双精度浮点(*),但按位运算符(
&
|
~
)是根据对32位整数的运算定义的。执行逐位操作将数字转换为32位有符号整数,在执行计算之前,会丢失任何分数和高于32位的位,然后再转换回数字

因此,在没有实际效果的情况下执行按位操作,例如0位的右移
>0
,是一种对数字进行四舍五入并确保其在32位整数范围内的快速方法。此外,三重
>>
运算符在执行无符号运算后,将其计算结果转换为无符号整数,而不是其他运算符所做的有符号整数,因此可以使用它将负数转换为32位二补形式的大数。使用
>>0
可以确保得到一个介于0和0xFFFFFF之间的整数

在这种情况下,这很有用,因为ECMAScript根据32位无符号整数定义数组索引。因此,如果您试图以与ECMAScript第五版标准完全相同的方式实现
array.filter
,则可以将数字转换为32位无符号整数,如下所示

(实际上,这几乎没有实际需要,因为希望人们不会将
array.length
设置为
0.5
-1
1e21
'LEMONS'
。但我们谈论的是JavaScript作者,所以你永远不知道……)

总结:

1>>>0            === 1
-1>>>0           === 0xFFFFFFFF          -1>>0    === -1
1.7>>>0          === 1
0x100000002>>>0  === 2
1e21>>>0         === 0xDEA00000          1e21>>0  === -0x21600000
Infinity>>>0     === 0
NaN>>>0          === 0
null>>>0         === 0
'1'>>>0          === 1
'x'>>>0          === 0
Object>>>0       === 0

(*:嗯,它们的行为被定义为类似于浮点数。出于性能原因,如果某些JavaScript引擎在可能的情况下实际使用Int,我不会感到惊讶。但这将是一个您无法利用的实现细节。)

>
是无符号右移运算符
(),与
>
相反,签名的右移运算符

>>
更改负数移位的结果,因为它在移位时不保留符号位。这一点的后果可以通过解释者的例子来理解:

$ 1 >> 0
1
$ 0 >> 0
0
$ -1 >> 0
-1
$ 1 >>> 0
1
$ 0 >>> 0
0
$ -1 >>> 0
4294967295
$(-1 >>> 0).toString(16)
"ffffffff"
$ "cabbage" >>> 0
0
因此,这里可能要做的是获取长度,如果长度未定义或不是整数,则取0,如上面的
“coball”
示例所示。我认为在这种情况下,可以安全地假设
this.length
永远不会是
<0
。然而,我认为这个例子是一个令人讨厌的黑客行为,原因有两个:


  • 的行为有两个原因:

  • >>>的结果是一个“积分”

  • 未定义的>>>0=0(因为JS将尝试将LFS强制为数字上下文,这也适用于“foo”>>0等)

  • 请记住,JS中的数字内部表示为double。 这只是一种“快速”输入长度的基本方法


    但是,-1>>>0(oops,可能不是所需的长度!)

    在Mozilla的所有array extra方法实现中使用无符号右移运算符,以确保
    length
    属性是无符号32位整数

    数组对象的
    length
    属性在规范中如下所示:

    每个数组对象都有一个长度属性,其值总是小于232的非负整数

    此运算符是实现此操作的最短方法,内部数组方法使用此操作,但该方法不可访问,并且出于实现目的而存在于规范中

    Mozilla array extras实现试图做到兼容,请查看
    array.prototype.indexOf
    方法(§15.4.4.14)的描述:

    1.让O作为通过此值调用ToObject的结果 作为论据。 2.让lenValue作为调用O的[[Get]]内部方法的结果 参数“长度”。 3.设len为ToUint32(lenValue)。 ....
    如您所见,他们只是想重现
    ToUint32
    方法的行为,以符合ES3实现上的ES5规范,正如我前面所说的,这是最简单的方法。

    下面的示例Java代码解释得很好:

    int x = 64;
    
    System.out.println("x >>> 3 = "  + (x >>> 3));
    System.out.println("x >> 3 = "  + (x >> 3));
    System.out.println(Integer.toBinaryString(x >>> 3));
    System.out.println(Integer.toBinaryString(x >> 3));
    
    输出如下:

    x >>> 3 = 536870904
    x >> 3 = -8
    11111111111111111111111111000
    11111111111111111111111111111000
    

    伊万,这将使它移动0个位置;那句话不会改变任何事情。@Ivan,通常,我会说改变a值b 1. Let O be the result of calling ToObject passing the this value as the argument. 2. Let lenValue be the result of calling the [[Get]] internal method of O with the argument "length". 3. Let len be ToUint32(lenValue). ....
    int x = 64;
    
    System.out.println("x >>> 3 = "  + (x >>> 3));
    System.out.println("x >> 3 = "  + (x >> 3));
    System.out.println(Integer.toBinaryString(x >>> 3));
    System.out.println(Integer.toBinaryString(x >> 3));
    
    x >>> 3 = 536870904
    x >> 3 = -8
    11111111111111111111111111000
    11111111111111111111111111111000