[javascript] JavaScript >>> 연산자 란 무엇이며 어떻게 사용합니까?

필터 메소드를 Array에 추가하는 Mozilla 코드를 보았는데 혼란 스러웠습니다.

var len = this.length >>> 0;

>>> 전에 JavaScript에서 사용 된 적이 없습니다.
그것은 무엇이며 무엇을합니까?



답변

숫자가 아닌 숫자를 숫자로 변환하는 것이 아니라 부호없는 32 비트 정수로 표현할 수있는 숫자로 변환합니다.

자바 스크립트의 숫자가 배정 밀도 수레 (*)는 비트 연산자가 있지만 ( <<, >>, &, |~ )는 32 비트 정수에 대한 운영의 관점에서 정의된다. 비트 단위 연산을 수행하면 계산을 수행 한 다음 숫자로 다시 변환하기 전에 숫자를 32 비트 부호있는 정수로 변환하여 32보다 작은 분수와 상위 비트를 잃게됩니다.

따라서 0 비트의 오른쪽 이동과 같이 실제 효과없이 비트 단위 연산을 수행하면 >>0숫자를 반올림하여 32 비트 int 범위에있게됩니다. 또한 삼항 >>>연산자는 부호없는 연산을 수행 한 후 계산 결과를 다른 사람이하는 부호있는 정수가 아닌 부호없는 정수로 Number로 변환하므로 음수를 32 비트 2의 보수로 변환하는 데 사용할 수 있습니다. 큰 숫자로 버전. 를 사용 >>>0하면 0에서 0xFFFFFFFF 사이의 정수를 사용할 수 있습니다.

이 경우 ECMAScript는 32 비트 부호없는 정수로 배열 인덱스를 정의하기 때문에 유용합니다. 따라서 array.filterECMAScript Fifth Edition 표준의 내용을 정확하게 복제하는 방식 으로 구현하려는 경우 숫자를 32 비트 부호없는 int로 캐스트합니다.

(실제로는 거의 실제적인 필요성이 거기의 희망 사람들이 설정 될 수 없습니다 등 array.length으로 0.5, -1, 1e21또는 'LEMONS'.하지만 당신은 모르실 있도록이, 우리는 약을 얘기 자바 스크립트 저자는 …)

요약:

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를 사용했다고해도 놀라지 않을 것입니다. 의 장점.)


답변

부호없는 오른쪽 이동 연산자는 속성이 부호없는 32 비트 정수임 을 보장하기 위해 Mozilla 모든 배열 여분의 메소드 구현에 사용됩니다.length 됩니다.

length배열 객체 의 속성은 사양에서 다음과 같이 설명 됩니다.

모든 Array 객체에는 값이 항상 2 32 미만의 음이 아닌 정수인 length 속성이 있습니다.

이 연산자는 가장 짧은 방법이며 내부 배열 방법은 ToUint32 조작을 하지만 해당 메소드는 액세스 할 수 없으며 구현 목적으로 스펙에 존재합니다.

Mozilla 배열 엑스트라 구현은 ECMAScript 5를 준수 하려고 시도 합니다.Array.prototype.indexOf 방법 (§ 15.4.4.14)을보십시오.

1. O가 this 값을 전달하는 ToObject를 호출 한 결과로 둡니다.
   논쟁으로.
2. lenValue가 O의 [[Get]] 내부 메소드를 호출 한 결과가되게하십시오.
   "길이"인수
3. len하자  ToUint32 (lenValue)로 설정하십시오 .
....

보시다시피 ToUint32ES3 구현에서 ES5 사양을 준수하기 위해 메소드 의 동작을 재현하기를 원합니다. 앞에서 말했듯이 부호없는 오른쪽 시프트 연산자 가 가장 쉬운 방법입니다.


답변

이것이 부호없는 오른쪽 비트 시프트 연산자입니다. 이것과 부호있는 오른쪽 비트 시프트 연산자 의 차이점 은 부호없는 오른쪽 비트 시프트 연산자 ( >>> )가 왼쪽에서 0으로 채워지고 부호있는 오른쪽 비트 시프트 연산자 ( >> )가 부호 비트로 채워진다는 것입니다 이동할 때 숫자 값의 부호를 유지합니다.


답변

디리스 는 운영자가 무엇이며 무엇을 하는지를 충분히 설명했습니다. 그 의미는 다음과 같습니다 / 사용 된 이유 :

원하는 방향을 이동하는 것은 0반환에게 원래의 번호를 수행하고 주조 할 것이다 null0. 당신이보고있는 예제 코드 가 숫자 인 경우에도 숫자 this.length >>> 0임을 확인하는 데 사용 하는 것 같습니다lenthis.length 는 정의되지 않은 .

많은 사람들에게 비트 단위 연산은 불분명합니다 (더글러스 크로포드 / jslint는 그러한 것들을 사용하지 말 것을 제안합니다). 그렇다는 것이 잘못되었다는 것을 의미하는 것은 아니지만 코드를 더 읽기 쉽게 만드는 더 유리하고 친숙한 방법이 있습니다. 그 보장하기 위해 더 명확한 방법 len이다는 0다음 두 가지 방법 중 하나입니다.

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

또는

// Cast this.length to a number, or use 0 if this.length is
// NaN/undefined (evaluates to false)
var len = +this.length || 0; 


답변

>>>는 IS 부호 오른쪽 시프트 연산자 ( 페이지. 자바 스크립트 1.5 사양의 76 )에 반대로 >>상기 서명 오른쪽 시프트 연산자.

>>>음수를 이동 하면 부호 비트가 유지되지 않으므로 음수를 이동 한 결과가 변경 됩니다 . 이것의 결과는 예를 들어 해석기에서 이해할 수 있습니다.

$ 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

따라서 여기서 수행하려는 것은 길이를 가져 오거나 "cabbage"위 의 예에 따라 길이가 정의되지 않았거나 정수가 아닌 경우 0을 얻는 것 입니다. 나는이 경우 this.length결코 없을 것이라고 가정하는 것이 안전하다고 생각 한다 < 0. 그럼에도 불구하고, 나는 이 예제가 두 가지 이유로 불쾌한 핵 이라고 주장합니다 .

  1. <<<음수 를 사용할 때 의 동작으로 , 위의 예에서 부작용이 발생하지 않았을 수 있습니다.

  2. 이 질문의 존재가 확인하기 때문에 코드의 의도는 분명하지 않습니다 .

모범 사례는 성능이 절대적으로 중요하지 않은 한 더 읽기 쉬운 것을 사용하는 것입니다.

isNaN(parseInt(foo)) ? 0 : parseInt(foo)


답변

두 가지 이유 :

  1. >>>의 결과는 “통합”입니다

  2. undefined >>> 0 = 0 (JS가 LFS를 숫자 컨텍스트로 강제 변환하려고 시도하기 때문에 “foo”에서 작동합니다. >>> 0 등)

JS의 숫자는 내부 표현이 double이라는 것을 기억하십시오. 그것은 길이에 대한 기본적인 입력 상태의 “빠른”방법입니다.

그러나 -1 >>> 0 (원하는 길이가 아닐 수도 있습니다!)


답변

아래 샘플 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