물결표가 표현식 앞에있을 때 어떤 역할을합니까?


답변:


268

~A는 비트 연산자 피연산자의 모든 비트를 플립.

예를 들어 숫자가 1인 경우 IEEE 754 float 의 이진 표현 (JavaScript에서 숫자를 처리하는 방법)은 다음과 같습니다.

0011 1111 1111 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000

따라서 ~피연산자를 32 비트 정수로 변환합니다 (JavaScript의 비트 연산자는 그렇게합니다) ...

0000 0000 0000 0000 0000 0000 0000 0001

음수이면 2의 보수로 저장됩니다. 모든 비트를 반전시키고 1을 더하십시오.

... 그리고 모든 비트를 뒤집습니다 ...

1111 1111 1111 1111 1111 1111 1111 1110

그렇다면 어떻게 사용합니까? 언제 사용할 수 있습니까?

꽤 많은 용도가 있습니다. 저수준의 물건을 쓰고 있다면 편리합니다. 응용 프로그램을 프로파일 링하고 병목 현상을 발견 한 경우 비트 단위의 트릭을 사용하여 성능을 향상시킬 수 있습니다 ( 훨씬 더 큰 가방에서 하나의 가능한 도구로).

그것은 또한 (일반적으로) 불분명 트릭indexOf()s의 ' 발견 에 반환 값 truthy을 (하는 동안 발견되지falsy ) 사람들이 자주 배로 32 비트 숫자를 절단 (및 소수 자릿수를 떨어 뜨리는 측면 효과를 사용, 실제로 Math.floor()양수 와 동일 ).

내가 말할 불분명 는이에 사용되는 즉시 분명 무엇 아니기 때문에. 일반적으로 코드를 읽는 다른 사람들과 명확하게 통신하기를 원합니다. 사용하는 것이 멋지게 보일~ 수 있지만 일반적으로 자신의 이익을 위해 너무 영리합니다. :)

그것은 자바 스크립트가 가지고있는 이제 덜 관련이 Array.prototype.includes()String.prototype.includes(). 부울 값을 반환합니다. 대상 플랫폼에서 지원하는 경우 문자열 또는 배열에 값이 있는지 테스트하기 위해이를 선호해야합니다.


2
불쾌한 말이 맞습니까? 그것이 작동하면 나는 그것을 언어의 관용구라고 부릅니다. 많은 관용구가 있습니다. 일단 당신이 그들을 배우면 그들은 명확하지 않습니다. 목록 이해는 파이썬에서 모르고 더 자세한 루프로 수행 할 수 있다면 명확하지 않지만 파이썬 프로그래머에게 절대 사용하지 말라고 요구하지는 않습니다. 마찬가지로 value = value || defaultJavaScript에서도 사용할 수 있고 사용할 수없는 경우를 알고있는 한 일반적이고 유효한 관용구입니다.
gman

3
@ gman 누군가가 그것을 사용하는지 여부는 실제로 중요하지 않다고 생각합니다. 목록 이해 (언어 기능)를 이것과 비교하는 것은 실제로 같은 것이 아니라고 생각합니다 ( 일부 추가 문자를 입력하지 않는 영리한 방법). 불쾌한 용어가 너무 가혹 하다고 생각되면 언제든지 답변을 편집하십시오.
alex

2
아마도 더 일반적인 예는 v = t ? a : b;입니다. 나는 var v; if (t} { v = a; } else { v = b; }일반적으로 5 + 라인에서 깨진 것보다 훨씬 명확 하고 var v = b; if (t) { v = a; }일반적으로 4 + 라인 보다 명확하다는 것을 알았습니다 . 그러나 나는 ? :두 번째 또는 세 번째 방법을 선호하는 운영자에 익숙하지 않은 많은 사람들을 알고 있습니다. 첫 번째가 더 읽기 쉽다는 것을 알았습니다. 나는 일반적인 원칙에 동의하고 코드를 명확하게하고 해킹을 사용하지 마십시오. 나는 ~v.indexOf('...')그것을 배운 후에는 매우 분명한 것으로 보입니다 .
gman

9
많은 개발자와 함께 대기업에서 일할 때 코드를 명확하게 작성하고 (영어) 문서화하기를 원합니다. 가비지 콜렉션이있는 언어에서 높은 수준의 코딩 포인트는 이진 연산에 대한 생각을 피하는 것이며, 많은 프론트 엔드 개발자는 자신의 벨트 아래에서 어셈블리 언어 경험을 가지고 있지 않습니다.
user2867288

3
나는 ~관용적 이라고 부르지 않을 것 입니다. 기술적으로는 언어 사양의 일부 이지만, 일반적으로 사용 되는 언어의 일부는 아닙니다 .
worc

110

indexOf()식 앞에 효과적으로 사용하면 직접 반환되는 숫자 인덱스 대신 사실 / 거짓 결과가 나타납니다.

리턴 값이있는 경우 -1, 다음 ~-1이다 0때문에 -1모든 1 비트의 문자열이다. 0보다 크거나 같은 값은 0이 아닌 결과를 제공합니다. 그러므로,

if (~someString.indexOf(something)) {
}

원인 것 if"뭔가" "someString"에있을 때 실행하는 코드를. .indexOf()부울로 직접 사용하려고하면 때로는 0을 반환하기 때문에 작동하지 않습니다 ( "뭔가"가 문자열의 시작 부분에있을 때).

물론 이것은 작동합니다.

if (someString.indexOf(something) >= 0) {
}

그리고 훨씬 덜 신비 롭습니다.

때때로 당신은 또한 이것을 볼 것입니다 :

var i = ~~something;

~연산자를 두 번 사용하면 문자열을 32 비트 정수로 빠르게 변환 할 수 있습니다. 첫 번째 ~는 변환을 수행하고 두 번째 ~는 비트를 뒤집습니다. 물론 연산자를 숫자로 변환 할 수없는 것에 적용 NaN하면 결과적으로 얻을 수 있습니다. ( 편집 — 실제로 두 번째 ~로 적용되지만 아이디어가 나옵니다.)


2
비트 단위로 부정하지 않으려 ~는 경우 정수에서 수행 할 때와 같습니다 -(x + 1).
Fabrício Matté

물론, 당신도 알다시피,처럼 보인다 NEGATIVE 숫자 값이 음수 부울 사람뿐만 아니라에서 1 위를 반환해야합니다. 그러나 JS 중 하나만 실패합니다.
wwaawaw

7
@adlwalrus 잘 전통 0있는 false0이 아닌 인 true70 년대와 프로그래밍 언어를 다른 당시 현대 시스템의 아마 많은 적어도 C에 날짜 웨이 다시. 하드웨어가 작동하는 방식에서 비롯된 것일 수 있습니다. 많은 CPU가 작업 후 0 비트를 설정하고 해당 분기 명령을 사용하여 테스트합니다.
Pointy

4
32 비트 int로 변환하는 더 빠른 방법 | 0은이 경우 하나의 작업 만입니다.
alex

@alex는 실제로 ~~동일한 애플리케이션의 간단한 응용 프로그램을 해석하지 않아도 런타임을 신뢰할 수는 없습니다 .
Pointy

30

~것입니다 비트 NOT 연산자 , ~x과 거의 동일합니다 -(x+1). 이해하기가 더 쉽습니다. 그래서:

~2;    // -(2+1) ==> -3

고려하십시오 -(x+1). -1해당 작업을 수행하여을 생성 할 수 있습니다 0.

다시 말해, ~숫자 값 범위와 함께 사용 하면 입력 값에 대해서만 잘못된 값 ( false에서 시작으로 0) 을 생성하고 -1그렇지 않으면 다른 값을 생성합니다.

아시다시피, -1일반적으로 센티넬 값 이라고 합니다 . C 언어에서 성공실패 에 대한 >= 0값을 리턴하는 많은 함수에 사용 됩니다. JavaScript에서 동일한 반환 값 규칙이 있습니다.-1indexOf()

이런 식으로 다른 문자열에서 하위 문자열의 존재 유무를 확인하는 것이 일반적입니다.

var a = "Hello Baby";

if (a.indexOf("Ba") >= 0) {
    // found it
}
if (a.indexOf("Ba") != -1) { 
    // found it
}

if (a.indexOf("aB") < 0) { 
    // not found
}
if (a.indexOf( "aB" ) == -1) { 
    // not found
}

그러나 ~다음과 같이 쉽게 수행 할 수 있습니다

var a = "Hello Baby";

~a.indexOf("Ba");         // -7   -> truthy
if (~a.indexOf("Ba")) {   // true
    // found it
}

~a.indexOf("aB");         // 0    -> falsy
!~a.indexOf("aB");        // true
if (!~a.indexOf( "aB" )) {  // true
    // not found
}

JS : Types & Grammar 작성자 : Kyle Simpson


1
그것은이다 확실히 사람이 작동하게 배경을 이해하지 못하는 경우에도, 액면 그대로 이해하는 것이 더 쉽습니다. -(x+1)if 문에서 그것을 보았는지 다시 살펴볼 것 입니다. 물결표는 Javascript의 0 기반 특성을 보완하기 위해 수행중인 작업을 정확하게 알려줍니다. 또한, 괄호가 적을수록 읽기
정규 Joe

초기 검사 코드 블록 if (a.indexOf("Ba") > -1) {// found} //true에서는 물결표 예제보다 약간 길지만 사용자가 제공 한 두 예제보다 훨씬 작고 새로운 프로그래머에게는 var opinion = !~-1 ? 'more' : 'less'이해할 수있는 것을 사용하여 입력을 줄일 수 있습니다.
HalfMens

25

~indexOf(item) 꽤 자주 나오고 여기에 대한 답변은 훌륭하지만 일부 사람들은 그것을 사용하는 방법을 알고 이론을 "건너 뛸"것만 필요할 수도 있습니다.

   if (~list.indexOf(item)) {
     // item in list
   } else {
     // item *not* in list
   }

1
동의합니다. 에어 비앤비 자바 스크립트 스타일 가이드 것을 허용하지 ++그리고 --그들은 아직 어떻게 든 "과도한 trickiness 장려"하기 때문에 ~(그림자에 숨어) 생존을 github.com/airbnb/javascript/issues/540
Shanimal

@Shanimal 대안은 list.indexOf(item) >= 0또는 ... > -1javascript가 0부터 시작하므로 처음부터 이것을 해결하기로 선택하지 않았습니다. 또한 자바 스크립트에서 의미있는 일을하는 사람이라면 누구나 의견 (Airbnb와 동일)을 알고 있으며 ++, --일반적이지 않지만 그 의미를 유추 할 수 있습니다.
정규 조

@RegularJoe 나는 그것의 대부분에 동의합니다. 나는 개인적으로 필요하지 않은 ++--때문에 같은 원시적 인 방법 중 한 동안 map, forEach등 내 포인트 더 그들은 또한 고려하지 않은 이유에 대해입니다 ~증가 및 감소 연산자가 포함되어 사용되는 표준 어떤 때 지나치게 까다로운. CIS101이 의미가 없도록 무언가를 금지하는 것.
Shanimal

12

물결표 트릭을 사용 하여 결과 에서 진실한 값 을 만드는 것을 고려하는 사람들에게는 indexOf보다 명시 적이며 대신에 includes방법을String 사용하는 마술이 적습니다 .

'hello world'.includes('hello') //=> true
'hello world'.includes('kittens') //=> false

ES 2015부터는 새로운 표준 방법이므로 이전 브라우저에서는 작동하지 않습니다. 중요한 경우 String.prototype.includes polyfill 사용을 고려하십시오 .

이 기능은 동일한 구문을 사용하는 배열에도 사용할 수 있습니다 .

['apples', 'oranges', 'cherries'].includes('apples') //=> true
['apples', 'oranges', 'cherries'].includes('unicorns') //=> false

구형 브라우저 지원이 필요한 경우 Array.prototype.includes polyfill 은 다음과 같습니다 .


2
include ()를 사용하지 마십시오. 이 문서는 작성 당시의 모든 IE 버전 (이전의 브라우저뿐만 아니라)에서는 지원되지 않습니다. developer.mozilla.org/en/docs/Web/JavaScript/Reference/…
Onshop

8
또는 컴파일러 만 사용하면 최악의 공통 분모 JS 인터프리터에 따라 언어를 작성하는 대신보다 명확한 코드를 작성할 수 있습니다.
Kyle Baker

2
@Ben이 맞습니다. Netscape 4.72에서도 작동하지 않습니다.
mikemaccana
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.