답변:
~
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()
. 부울 값을 반환합니다. 대상 플랫폼에서 지원하는 경우 문자열 또는 배열에 값이 있는지 테스트하기 위해이를 선호해야합니다.
value = value || default
JavaScript에서도 사용할 수 있고 사용할 수없는 경우를 알고있는 한 일반적이고 유효한 관용구입니다.
v = t ? a : b;
입니다. 나는 var v; if (t} { v = a; } else { v = b; }
일반적으로 5 + 라인에서 깨진 것보다 훨씬 명확 하고 var v = b; if (t) { v = a; }
일반적으로 4 + 라인 보다 명확하다는 것을 알았습니다 . 그러나 나는 ? :
두 번째 또는 세 번째 방법을 선호하는 운영자에 익숙하지 않은 많은 사람들을 알고 있습니다. 첫 번째가 더 읽기 쉽다는 것을 알았습니다. 나는 일반적인 원칙에 동의하고 코드를 명확하게하고 해킹을 사용하지 마십시오. 나는 ~v.indexOf('...')
그것을 배운 후에는 매우 분명한 것으로 보입니다 .
~
관용적 이라고 부르지 않을 것 입니다. 기술적으로는 언어 사양의 일부 이지만, 일반적으로 사용 되는 언어의 일부는 아닙니다 .
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
하면 결과적으로 얻을 수 있습니다. ( 편집 — 실제로 두 번째 ~
로 적용되지만 아이디어가 나옵니다.)
~
는 경우 정수에서 수행 할 때와 같습니다 -(x + 1)
.
0
있는 false
0이 아닌 인 true
70 년대와 프로그래밍 언어를 다른 당시 현대 시스템의 아마 많은 적어도 C에 날짜 웨이 다시. 하드웨어가 작동하는 방식에서 비롯된 것일 수 있습니다. 많은 CPU가 작업 후 0 비트를 설정하고 해당 분기 명령을 사용하여 테스트합니다.
| 0
은이 경우 하나의 작업 만입니다.
~~
동일한 애플리케이션의 간단한 응용 프로그램을 해석하지 않아도 런타임을 신뢰할 수는 없습니다 .
는 ~
것입니다 비트 NOT 연산자 , ~x
과 거의 동일합니다 -(x+1)
. 이해하기가 더 쉽습니다. 그래서:
~2; // -(2+1) ==> -3
고려하십시오 -(x+1)
. -1
해당 작업을 수행하여을 생성 할 수 있습니다 0
.
다시 말해, ~
숫자 값 범위와 함께 사용 하면 입력 값에 대해서만 잘못된 값 ( false
에서 시작으로 0
) 을 생성하고 -1
그렇지 않으면 다른 값을 생성합니다.
아시다시피, -1
일반적으로 센티넬 값 이라고 합니다 . C 언어에서 성공 및 실패 에 대한 >= 0
값을 리턴하는 많은 함수에 사용 됩니다. JavaScript에서 동일한 반환 값 규칙이 있습니다.-1
indexOf()
이런 식으로 다른 문자열에서 하위 문자열의 존재 유무를 확인하는 것이 일반적입니다.
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
}
-(x+1)
if 문에서 그것을 보았는지 다시 살펴볼 것 입니다. 물결표는 Javascript의 0 기반 특성을 보완하기 위해 수행중인 작업을 정확하게 알려줍니다. 또한, 괄호가 적을수록 읽기
if (a.indexOf("Ba") > -1) {// found} //true
에서는 물결표 예제보다 약간 길지만 사용자가 제공 한 두 예제보다 훨씬 작고 새로운 프로그래머에게는 var opinion = !~-1 ? 'more' : 'less'
이해할 수있는 것을 사용하여 입력을 줄일 수 있습니다.
~indexOf(item)
꽤 자주 나오고 여기에 대한 답변은 훌륭하지만 일부 사람들은 그것을 사용하는 방법을 알고 이론을 "건너 뛸"것만 필요할 수도 있습니다.
if (~list.indexOf(item)) {
// item in list
} else {
// item *not* in list
}
++
그리고 --
그들은 아직 어떻게 든 "과도한 trickiness 장려"하기 때문에 ~
(그림자에 숨어) 생존을 github.com/airbnb/javascript/issues/540
list.indexOf(item) >= 0
또는 ... > -1
javascript가 0부터 시작하므로 처음부터 이것을 해결하기로 선택하지 않았습니다. 또한 자바 스크립트에서 의미있는 일을하는 사람이라면 누구나 의견 (Airbnb와 동일)을 알고 있으며 ++
, --
일반적이지 않지만 그 의미를 유추 할 수 있습니다.
++
및 --
때문에 같은 원시적 인 방법 중 한 동안 map
, forEach
등 내 포인트 더 그들은 또한 고려하지 않은 이유에 대해입니다 ~
증가 및 감소 연산자가 포함되어 사용되는 표준 어떤 때 지나치게 까다로운. CIS101이 의미가 없도록 무언가를 금지하는 것.
물결표 트릭을 사용 하여 결과 에서 진실한 값 을 만드는 것을 고려하는 사람들에게는 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 은 다음과 같습니다 .