이것은 !! JavaScript가 아닌 연산자입니까?


3105

인식하지 못하는 연산자를 사용하는 것으로 보이는 일부 코드는 다음과 같이 두 개의 느낌표 형태로 나타납니다 !!. 누군가이 연산자가 무엇을하는지 말해 줄 수 있습니까?

내가 본 상황은

this.vertical = vertical !== undefined ? !!vertical : this.vertical;

944
"당신에게있는 거 부울 쾅, 쾅"하여 기억
거스

75
기록을 위해 인용 된 것을하지 마십시오. 수행 if(vertical !== undefined) this.vertical = Boolean(vertical);- 훨씬 깨끗하고 무슨 일이 일어나고 있는지 명확, 불필요한 할당을 필요로하지 않는다 완전히 표준이며, (현재 FF와 크롬에) 그냥 빨리 jsperf.com/boolean-conversion-speed .
Phil H

73
!! 연산자가 아닙니다. 그냥! 연산자 두 번.
Vivek

11
기록적인 것만 Boolean(5/0)!!5/0
schabluk

63
@schabluk, 레코드 의 경우 작업 순서 는에서 !!5/0생성 한 Infinity것 보다을 (를) 생성 하는 것보다 낫 true습니다 Boolean(5/0). 연산자 는 연산자보다 우선 순위가 높기 때문에 일명 - !!5/0과 같습니다 . 더블 뱅을 사용하여 불리언을 만들 려면을 사용해야 합니다. (!!5)/0true/0!/5/0!!(5/0)
matty

답변:


2745

로 변환 Object합니다 boolean. 은 (예를 들어 falsey 있었다면 0, null, undefined, 등)이있을 것이다 false, 그렇지 않으면 true.

!oObject  // inverted boolean
!!oObject // non inverted boolean so true boolean representation

따라서 !!연산자는 아닙니다 !. 연산자는 두 번입니다.

실제 예제 "Test IE version":

const isIE8 = !! navigator.userAgent.match(/MSIE 8.0/);  
console.log(isIE8); // returns true or false 

당신이 ⇒

console.log(navigator.userAgent.match(/MSIE 8.0/));  
// returns either an Array or null  

하지만 ⇒

console.log(!!navigator.userAgent.match(/MSIE 8.0/));  
// returns either true or false

123
비 부울을 역 부울로 변환합니다 (예를 들어, 5는 JS의 거짓 값이 아니기 때문에! 5는 false가됩니다). 그러면 부울이 반전되어 원래 값을 부울로 얻습니다 (그래서 !! 5는 사실이다).

111
이를 설명하는 쉬운 방법은 다음과 같습니다. Boolean (5) === !! 5; 같은 캐스팅, 적은 문자.
Micah Snyder

39
이 값은 진리 값을 부울 true로 변환하고 허위 값을 부울 false로 변환하는 데 사용됩니다.
thetoolman

13
@Micah Snyder는 JavaScript에서 new Boolean ()으로 부울 상자를 만드는 객체를 만드는 대신 부울 프리미티브를 사용하는 것이 좋습니다. 다음은 차이점을 보여주는 예입니다. jsfiddle.net/eekbu
victorvartan

4
내가 아는 한,이 bang-bang 패턴은 if (… _ 문 내에서는 유용하지 않으며 부울을 반환해야하는 함수의 return 문에서만 유용합니다.
rds

854

형식 변환을 수행하는 끔찍한 방법입니다.

!이다 NOT . 그래서이 !true있다 false, 그리고 !false이다 true. !0이다 true, 그리고 !1이다 false.

따라서 값을 부울로 변환 한 다음 뒤집은 다음 다시 뒤집습니다.

// Maximum Obscurity:
val.enabled = !!userId;

// Partial Obscurity:
val.enabled = (userId != 0) ? true : false;

// And finally, much easier to understand:
val.enabled = (userId != 0);

74
!! 거짓 = 거짓. !! true = true
cllpse

89
"이해하기가 훨씬 쉬워졌습니다"변형이 여기서 이해하기가 훨씬 더 쉽습니까? 0에 대한 검사는 0에 대한 실제 검사가 아니지만 Javascript가 0 userId ? true : false 으로 간주하는 다소 이상한 값 목록에 대한 검사 입니다. 변환이 진행 중이고 userId의 값이 명시 적으로 설정된 경우를 처리합니다.undefined
Ben Regenspan

54
내 뇌는 디코딩 문제가 없습니다 !!var로를 Boolean(var).. 그리고 !!대안보다 빠르게 (이하 프로세스 지침) 및 짧습니다.
adamJLev

7
@RickyClarkson 문법적으로 필요하지 않기 때문에 주로 가독성을 제공합니다. 일부는 항상 조건을 괄호로 묶어 나머지 표현식과 구별되도록하는 규칙을 사용합니다.
Dave Rager

8
나는 이것에 동의하지 않습니다. userId != 0마찬가지입니다 null, NaN그리고 undefined,하지만에 대한 허위 false. 당신이 그 행동을 정확히 원한다면, 당신은 그것에 대해 분명해야합니다. 하지만 정확히 같은 일을하더라도 !!userId, 당신이 있는지 분명하지 않다 원하는 그 값이 아니면 그냥 자바 스크립트의 타입 변환 규칙을 고려 실패했는지, 여기에 거짓을 마련 할 수 있습니다.
philh

449

!!expr식 의 진실성 에 따라 부울 값 ( true또는 false)을 반환합니다 . 부울이 아닌 유형에 사용될 때 더 의미가 있습니다. 다음 예, 특히 세 번째 예 이상을 고려하십시오.

          !!false === false
           !!true === true

              !!0 === false
!!parseInt("foo") === false // NaN is falsy
              !!1 === true
             !!-1 === true  // -1 is truthy

             !!"" === false // empty string is falsy
          !!"foo" === true  // non-empty string is truthy
        !!"false" === true  // ...even if it contains a falsy value

     !!window.foo === false // undefined is falsy
           !!null === false // null is falsy

             !!{} === true  // an (empty) object is truthy
             !![] === true  // an (empty) array is truthy; PHP programmers beware!

63
주목할만한 가치 :!!new Boolean(false) // true
Camilo Martin

43
... 그러나!!Boolean(false) // false
Camilo Martin

97
new Boolean(false)거짓 값을 포함하더라도 대상은 진실이며 대상은 진실입니다!
살만 A

3
예 알아요,하지만 (대부분의 기본 생성자는 사실을 고려 String, Number, Date, 등이) 너무 함수로 호출 할 의미를, 그러나이 경우 결과는 다르다!
Camilo Martin

4
@CamiloMartin : 방금 깨달았 new Boolean(false)다시 표시 object하면서 Boolean(false)반환 프리미티브 false . 이것이 의미가 있기를 바랍니다.
살만 A

155

차를 끓이십시오 :

!!연산자가 아닙니다. !논리적 "not"연산자 인 이중 사용입니다 .


이론에 의하면:

! 값이 아닌 "진실"을 결정합니다.

  • 진실은 즉 false하지 않습니다 true(이유 그 !false결과 true)

  • 진실은 즉 true하지 않습니다 false(이유 그 !true결과 false)


!!값이 아닌 것에 대한 "진실"을 결정합니다 .

  • 진실은 즉 true하지 하지 true (의 그 이유는 !!true결과 true)

  • 진실은 즉 false하지 하지 false (의 그 이유는 !!false결과 false)


우리가 비교에서 결정하고자하는 것은 참조 값에 대한 "진실" 입니다. 것은 참조 자체 입니다. 값이 false(또는 잘못된) 것으로 예상되거나 값이 typeof가 아닌 것으로 예상 하더라도 값에 대한 진실을 알고 싶어하는 유스 케이스가 있습니다 boolean.


실제로:

동적 타이핑 (일명 "덕 타이핑")을 통해 기능 기능 (이 경우 플랫폼 호환성)을 감지하는 간결한 기능을 고려하십시오 . true사용자 브라우저가 HTML5 <audio>요소를 지원하는 경우 반환하는 함수를 작성하려고 하지만 <audio>정의되지 않은 경우 함수가 오류를 발생시키지 않도록합니다 . try ... catch가능한 오류를 처리하는 데 사용하고 싶지 않습니다 (매우 심각하기 때문에). 또한 기능에 대한 진실을 일관되게 밝히지 않는 함수 내부에서 검사를 사용하고 싶지 않습니다 (예 :document.createElement('audio')<audio> HTML5 <audio>가 지원되지 않는 경우에도 여전히 요소를 생성합니다 ).


세 가지 접근 방식은 다음과 같습니다.

// this won't tell us anything about HTML5 `<audio>` as a feature
var foo = function(tag, atr) { return document.createElement(tag)[atr]; }

// this won't return true if the feature is detected (although it works just fine)
var bar = function(tag, atr) { return !document.createElement(tag)[atr]; }

// this is the concise, feature-detecting solution we want
var baz = function(tag, atr) { return !!document.createElement(tag)[atr]; }

foo('audio', 'preload'); // returns "auto"
bar('audio', 'preload'); // returns false
baz('audio', 'preload'); // returns true

각 함수는 a <tag>와 a에 대한 인수를 허용합니다 .attribute 하지만 비교가 결정한 내용에 따라 서로 다른 값을 반환합니다.

그러나 더 많은 것이 있습니다!

여러분 중 일부는이 특정 예 에서 문제의 객체에 속성 있는지 확인 하는 약간 더 성능이 좋은 방법을 사용하여 속성을 간단히 확인할 수 있음을 알았습니다 . 이를 수행하는 두 가지 방법이 있습니다.

// the native `hasOwnProperty` method
var qux = function(tag, atr) { return document.createElement(tag).hasOwnProperty(atr); }

// the `in` operator
var quux = function(tag, atr) { return atr in document.createElement(tag); }

qux('audio', 'preload');  // returns true
quux('audio', 'preload'); // returns true

우리는 ...

그러나 이러한 상황이 드물기는하지만 true부울이 아닌 정의되지 않은 값에서 가져 오는 가장 간결하고 성능이 좋으며 가장 선호되는 방법 이 실제로 사용 되는 몇 가지 시나리오가있을 수 있습니다 !!. 잘하면 이것은 말도 안되게 정리합니다.


1
완전히 멋진 답변이지만, 나는 유틸리티를 보지 못합니다! 구성합니다. 이후if() 문이 이미 명시 적으로 부울에 테스트 함수의 반환 값을 캐스팅, 부울 할 수있는 표현을 캐스팅 중복 - "truthiness"=== 사실부터가 먼만큼 if()문 어쨌든 간다. 아니면 실제로 부울하기 위해 진실한 표현이 필요한 시나리오가 누락 true되었습니까?
Tom Auger

1
@TomAuger if()문은 잘못된 값에 대해 부울을 캐스팅하지만 실제로 객체에 부울 플래그를 설정하려고한다고 가정하면 if()명령문 과 같이 캐스팅 되지 않습니다. 예를 들어 object.hasTheThing = !!castTheReturnValToBoolNoMatterWhat()중 하나를 설정합니다 true또는 false대신 실제 반환 값의. 또 다른 예는 아마 모든 관리자는 다음 id0비 관리자는 ID입니다 1이상. 얻기 위해true누군가가 관리자가 아닌 사람이되도록 할 수 있습니다 person.isNotAdmin = !!admin.id. 유스 케이스는 거의 없지만 간결한 경우입니다.
베니

103

!!오른쪽의 값을 동등한 부울 값으로 변환합니다. (가난한 사람의 "유형 캐스팅"방식을 생각하십시오). 이것의 목적은 코드 상관하지 않는 독자에게 전달하기 위해 일반적으로 어떤 값이 변수이지만, 그것의 어떤 "진리"값 입니다.


4
또는 오른쪽의 부울 값의 경우 아무 것도 수행하지 않습니다.
Daniel A. White

3
@Daniel : !여전히 값을 오른쪽으로 뒤집습니다. 부울의 경우 가장 오른쪽에 !있는 값이 무시되고 가장 왼쪽에있는 값이 !다시 무시됩니다. 결과적으로 변화는 없지만 대부분의 엔진은 이중 부정을위한 op 코드를 생성합니다.
Crescent Fresh

그러나 요점은 무엇입니까? if(0){...Javascript를 이미 알고 있다면 이것이 잘못된 것입니다. 왜 말하는 것이 더 낫 if(!!0){...습니까?
CodyBugstein

요점은 그 내용을 모르는 변수에 대한 것입니다. 정수 또는 문자열, 객체 또는 null, undefined 등일 수 있습니다. 이는 존재 여부를 테스트하는 쉬운 방법입니다.
mix3d

71

!!foo단항 not 연산자를 두 번 적용하고 단항 더하기 +foo를 사용 하여 숫자로 캐스트하고 빈 문자열을 연결하는 것과 유사한 부울 유형으로 캐스트하는 데 사용됩니다.''+foo 을 로 캐스트하는 .

이러한 해킹 대신 기본 유형에 해당하는 생성자 함수 사용하여 ( 사용 하지 않고new ) 명시 적으로 값을 캐스트 할 수 있습니다.

Boolean(foo) === !!foo
Number(foo)  === +foo
String(foo)  === ''+foo

그러나 instanceof에 문제가 발생할 수 있습니다. new Boolean (1) instanceof Object-> true !! 1 instanceof Object-> false
Seamus

13
아니, 당신은 할 수 없습니다 :없이 생성자 함수가 호출 통지 것을 new- 명시 적으로 내 대답에 언급
크리스토프

2
환상적입니다! 이는 "0"이있는 문자열을 true 대신 false로 평가해야 할 때 약간의 해킹에 유용합니다. (즉, 문자열로 읽히기 때문에 selects에서 값을 읽을 때). 그래서, 당신은 asuming, 부정적 (부울 거짓)로 "0"을 고려할 경우 x="0"만 수행 x=!!+x; //false과 같은 인 Boolean(Number(x))부울 번호 (또는 + X 것은) 않습니다 false로 평가 0 문자열 "0"으로 변환 한 다음 (!! x)는 그것을 직접 불리언으로 캐스팅합니다. 쉬워요!
DiegoDD

2
@DiegoDD 왜 당신은 !!+x대 를 선택 x !== "0"하시겠습니까?
placeybordeaux

예를 들어 @placeybordeaux는 값을 다른 변수와 비교할지 여부에 관계없이 값을 변환하여 다른 변수에 할당 할 수 있기 때문입니다.
DiegoDD

67

작업의 절반을 수행하는 많은 답변. 예, !!X"X의 진실성 [부울로 표현됨]이라고 읽을 수 있습니다. 그러나 !!실제로 말해서 단일 변수가 진실인지 거짓인지 알아내는 데 중요하지 않습니다. !!myVar === true그냥 동일합니다 myVar. 비교!!X"실제"부울과 하는 것은 실제로 유용하지 않습니다.

당신이 얻는 !!것은 서로에 대해 여러 변수의 진실성을 확인하는 능력입니다 것은 반복 가능하고 표준화 된 (그리고 JSLint 친화적 인) 방식 입니다.

단순히 캐스팅 :(

그건...

  • 0 === false입니다 false.
  • !!0 === false입니다 true.

위의 내용은 그렇게 유용하지 않습니다. if (!0)와 동일한 결과를 제공합니다 if (!!0 === false). 변수를 부울로 캐스트 한 다음 "참"부울과 비교하는 좋은 사례는 생각할 수 없습니다.

JSLint의 지시에 따라 "== 및! ="를 참조하십시오 (참고 : Crockford가 약간의 사이트를 이동하고 있습니다. 해당 링크는 어느 시점에서 죽기 쉽습니다).

== 및! = 연산자는 비교하기 전에 강제 변환을 수행합니다. '\ t \ r \ n'== 0이 참이기 때문에 이것은 나쁩니다. 유형 오류를 마스크 할 수 있습니다. JSLint는 ==가 올바르게 사용되고 있는지 확실하게 확인할 수 없으므로 == 및! =를 전혀 사용하지 않고 항상보다 안정적인 === 및! == 연산자를 사용하는 것이 가장 좋습니다.

값이 진실이거나 허위임을 신경 쓰는 경우 짧은 형식을 사용하십시오. 대신에
(foo != 0)

그냥 말해
(foo)

대신에
(foo == 0)

말하다
(!foo)

참고 일부 있다는 것을 직관적 경우 부울이 숫자로 캐스팅 될 것입니다 ( true에 캐스팅 1false0숫자로 부울을 비교할 때). 이 경우 !!정신적으로 유용 할 수 있습니다. 다시, 이것은 부울이 아닌 것을 하드 타입의 부울과 비교하는 경우입니다. if (-1)여전히 여기가는 길입니다.

╔═══════════════════════════════════════╦═══════════════════╦═══════════╗
               Original                    Equivalent       Result   
╠═══════════════════════════════════════╬═══════════════════╬═══════════╣
 if (-1 == true) console.log("spam")    if (-1 == 1)       undefined 
 if (-1 == false) console.log("spam")   if (-1 == 0)       undefined 
   Order doesn't matter...                                           
 if (true == -1) console.log("spam")    if (1 == -1)       undefined 
╠═══════════════════════════════════════╬═══════════════════╬═══════════╣
 if (!!-1 == true) console.log("spam")  if (true == true)  spam       better
╠═══════════════════════════════════════╬═══════════════════╬═══════════╣
 if (-1) console.log("spam")            if (truthy)        spam       still best
╚═══════════════════════════════════════╩═══════════════════╩═══════════╝

그리고 엔진에 따라 상황이 훨씬 더 어려워집니다. 예를 들어 WScript가 상을 수상합니다.

function test()
{
    return (1 === 1);
}
WScript.echo(test());

역사적인 Windows jive 때문에 메시지 상자에 -1이 출력됩니다! cmd.exe 프롬프트에서 시도해보십시오! 그러나 WScript.echo(-1 == test())여전히 0 또는 WScript를 제공합니다 false. 멀리 봐 끔찍 해요

진실성 비교 :)

그러나 두 가지 가치가 있다면 동일한 진실성 / 거짓 성을 확인해야합니까?

우리가있는 척 myVar1 = 0;하고 myVar2 = undefined;.

  • myVar1 === myVar2이다 0 === undefined명백하게 거짓입니다.
  • !!myVar1 === !!myVar2이다 !!0 === !!undefined와 사실이다! 같은 진실성! (이 경우, 둘 다 "거짓의 진실성을가집니다".

따라서 실제로 "부울 캐스트 변수"를 사용해야하는 유일한 장소는 두 변수가 동일한 진실성을 갖는지 확인하는 상황이있는 것입니다 . 즉, 사용 !!두 바르가 있는지 확인해야하는 경우 truthy 또는 둘 모두 falsy 모두 , (또는하지 않음), 동등의 (여부) truthiness .

나는 그 미손에 대한 유인되지 않은 훌륭한 유스 케이스를 생각할 수 없다. 양식에 "연결된"필드가 있습니까?

if (!!customerInput.spouseName !== !!customerInput.spouseAge ) {
    errorObjects.spouse = "Please either enter a valid name AND age " 
        + "for your spouse or leave all spouse fields blank.";
}

따라서 배우자 이름과 나이에 대해 모두 진실 하거나 허위 인 경우 계속할 수 있습니다. 그렇지 않으면 가치가있는 필드 (또는 매우 이른 결혼 생활)가 하나 있고 errorObjects컬렉션 에 추가 오류가 발생해야합니다 .


2017 년 10 월 24 일, 2 월 19 일 편집 :

명시 적 부울 값이 필요한 타사 라이브러리

흥미로운 사례 !!가 있습니다 ... 타사 라이브러리가 명시적인 부울 값을 기대할 때 유용 할 수 있습니다.

예를 들어, JSX (React)의 False는 단순한 허위로 유발되지 않는 특별한 의미 를 갖습니다. JSX에서 다음과 같은 것을 반환하려고 시도하면 int in messageCount...

{messageCount && <div>You have messages!</div>}

... 메시지가 없을 0때 React가 a를 렌더링하는 것을보고 놀랄 수도 있습니다 . JSX가 렌더링되지 않도록하려면 명시 적으로 false를 반환해야합니다. 위의 명령문은 0JSX를 정상적으로 렌더링하는을 반환 합니다. 그것은 당신이하지 않았다 Count: {messageCount && <div>Get your count to zero!</div>}(또는 덜 고안된 것을) 말할 수 없습니다 .

  • 한 수정 강제 변환 방방, 관련 0으로 !!0인을 false:
    {!!messageCount && <div>You have messages!</div>}

  • JSX의 문서는 더 명확하고 자체 주석 코드를 작성하며 비교를 사용하여 부울로 강제합니다.
    {messageCount > 0 && <div>You have messages!</div>}

  • 나는 삼항으로 자신을 조작하는 것이 더 편합니다.
    {messageCount ? <div>You have messages!</div> : false}

Typescript와 같은 거래 : 불리언을 반환하는 함수가 있거나 불리언 변수에 값을 할당하는 경우, 일반적으로 불리언 y 값을 반환 / 할당 할 수 없습니다. 강력하게 형식화 된 부울이어야합니다. 이것은 iff myObject가 강력하게 입력 되고 return !myObject;부울을 반환하는 함수 에는 작동하지만 return myObject;그렇지 않은 것을 의미합니다. return !!myObjectTypescript의 기대치와 일치 해야합니다 .

Typescript의 예외? 경우 myObject을했다 any, 당신은 다시 자바 스크립트의 서부에있어,없이 반환 할 수 있습니다 !!당신의 반환 형식이 부울 경우에도.

있다는 사실을 숙지 이러한 JSX & 타이프 라이터 규칙입니다 자바 스크립트가 아니라 고유의 것들 .

그러나 0렌더링 된 JSX에 이상한 것이 있으면 허위 관리를 느슨하게 생각하십시오.


좋은 설명입니다. 그래서 당신은 말할 것입니다! 이 작업자 기능 감지 예 에서 반드시 필요한 것은 아닙니까? if (!!window.Worker)
jk7

2
아니, 당신은 필요하지 않을 것입니다. 진실성과 true"외부 적으로"는 if. 계속 노력하고 있지만 q라이브러리 예제 에서와 같이 나중에 값을 다시 사용하는 경우 가독성을 제외하고 위의 복잡한 "진실성 비교"사례 이외의 부울 값에 진실성을 적용하는 것을 선호하는 이유는 생각할 수 없습니다. . 그러나 그때조차도 정보가 손실되는 지름길이며 매번 진실성을 평가하는 것이 더 낫습니다.
ruffin

반응은 우리가 사용하기 시작한 주된 이유입니다! 패턴이지만 매우 편리하고 반복 가능한 것입니다. 나는 근본적인 유형이 아니라 무언가의 진실성 또는 거짓에 대해 걱정할 필요가 있습니다.

의견이없는 공감대는 귀하의 우려를 해결하기가 어렵습니다! 무엇이 나빠 보이는지 알려 주시면 기꺼이 해결해 드리겠습니다.
ruffin

55

논리적 NOT 연산자입니다. 두 번 – 무언가를 부울로 변환하는 데 사용됩니다. 예 :

true === !!10

false === !!0

3
왜 지구상에서 그렇게하겠습니까? 사용 ! 연산자를 부울로 변환 한 다음 ===를 사용하여 유형을 비교 하시겠습니까? 타입 안전이없고 val> 0 또는 다른 것을 수행하십시오.
Darren Clark

43
@Darren : 유형을 비교하지 않습니다. 그는 자신의 답변에 명제를 작성하여 결과가 무엇인지 알려줍니다.
궤도에서 가벼움 경주


26

이중 not작업입니다. 첫 번째 !는 값을 부울로 변환하고 논리 값을 반전시킵니다. 두 번째 !는 논리 값을 되돌립니다.


26

!!운영자는 이중 부정을 초래 하는 것 같습니다 .

var foo = "Hello World!";

!foo // Result: false
!!foo // Result: true

23

Boolean()캐스팅 기능 의 동작을 시뮬레이션합니다 . 첫 번째 NOT는 주어진 피연산자에 관계없이 부울 값을 반환합니다. 두 번째는 NOT해당 Boolean값을 무효화 하므로 true변수 의 부울 값을 제공합니다 . 최종 결과는 Boolean()값에 함수를 사용하는 것과 같습니다 .


20

! "boolean not"은 기본적으로 "enable"값을 부울 반대쪽으로 타입 캐스트합니다. 두번째 ! 이 값을 뒤집습니다. 따라서 !!enable"활성화하지 않음"을 의미 enable하여 부울 값을 제공합니다 .


18

논리적 AND / OR과 결합 된 조건은 부울 값을 반환하지 않지만 && 및 첫 번째 성공 또는 ||의 경우 마지막 실패 또는 || 조건 체인의.

res = (1 && 2); // res is 2
res = (true && alert) // res is function alert()
res = ('foo' || alert) // res is 'foo'

조건을 실제 부울 리터럴로 캐스트하기 위해 이중 부정을 사용할 수 있습니다.

res = !!(1 && 2); // res is true
res = !!(true && alert) // res is true
res = !!('foo' || alert) // res is true

17

!!NOT작업을 두 번 함께 사용 !하고 값을 a로 변환 boolean하고 역전하는 경우 !!작동 방식 을 보여주는 간단한 예 는 다음과 같습니다.

처음에는 다음과 같은 장소가 있습니다.

var zero = 0;

그럼 당신은 어떻게 !0이 부울하고로 평가 변환됩니다, true0이기 때문에, falsy당신이 반전 된 가치를 얻을 부울로 변환, 그래서 그것이로 평가됩니다, 그래서, true.

!zero; //true

그러나 우리는 값 의 역상 불리언 버전 을 원하지 않기 때문에 결과를 얻기 위해 다시 역으로 할 수 있습니다! 우리가 다른 것을 사용하는 이유입니다! 입니다.

기본적으로 !!우리가 얻는 가치는 거짓, 진실 또는 문자열 등이 아닌 부울입니다.

따라서 Boolean자바 스크립트에서 함수를 사용하는 것과 같지만 값을 부울로 변환하는 쉽고 짧은 방법입니다.

var zero = 0;
!!zero; //false

15

!!구문은 JavaScript 표현식을 부울로 변환하는 간단한 방법입니다.

예를 들면 다음 !!"he shot me down" === true과 같습니다 !!0 === false.


2
중요한 차이점에 매우 가깝습니다. 열쇠는 그것이 0 === false거짓이며 !!0 === false사실입니다.
ruffin

14

단일 연산자가 아니며 두 개입니다. 다음과 같으며 값을 부울로 캐스팅하는 빠른 방법입니다.

val.enabled = !(!enable);

10

사람들이!를 재정의하는 C ++에서 남은 것으로 생각됩니다. 부울 연산자가 아닌 연산자입니다.

따라서이 경우 부정적인 (또는 긍정적) 대답을 얻으려면 먼저! 연산자는 부울을 가져 오지만 긍정적 인 경우를 확인하려면 !!를 사용하십시오.


10

ifwhile진술과 ?연산자를 사용 진리 값은 런타임에 코드의 어떤 지점을 확인합니다. 예를 들어, 0과 NaN 숫자와 빈 문자열은 거짓이지만 다른 숫자와 문자열은 참입니다. 객체는 참이지만 정의되지 않은 값이며 null모두 거짓입니다.

이중 부정 연산자 !!는 값의 진리 값을 계산합니다. 실제로 !!xmeans 두 연산자이며 !(!x)다음과 같이 작동합니다.

  • 경우 x, 거짓 값 !x입니다 true, 그리고 !!x이다 false.
  • 경우 x, 진정한 값 !x이다 false,하고 !!x있다 true.

부울 컨텍스트의 최상위에 사용될 때 ( if, while?)는 !!조작 된 행동이 조작은 행해지 지 않는다. 예를 들어, if (x)if (!!x)같은 일을 의미한다.

실용

그러나 몇 가지 실용적인 용도가 있습니다.

한 가지 용도는 객체를 실제 값으로 손실 압축하여 코드가 큰 객체에 대한 참조를 보유하지 않고 유지되도록하는 것입니다. 가비지 수집기 !!some_big_object대신 변수에 할당 하면 변수를 제거 some_big_object할 수 있습니다. 이는 null브라우저 기능 감지와 같이 정의되지 않은 값 과 같은 객체 또는 거짓 값을 생성하는 경우에 유용합니다 .

C의 해당 !!연산자 에 대한 답변 에서 언급 한 또 다른 용도 는 일반적인 오타 및 인쇄 진단을 찾는 "보풀이없는"도구를 사용하는 것입니다. 예를 들어, C와 JavaScript 모두에서 부울 연산에 대한 몇 가지 일반적인 오타는 출력이 부울이 아닌 다른 동작을 생성합니다.

  • if (a = b)할당은 뒤에 진실의 가치를 사용 b한다; if (a == b)평등 비교입니다.
  • if (a & b)비트 AND입니다. if (a && b)논리 AND입니다. 2 & 5is 0(false value); 2 && 5사실이다.

!!연산자는 무엇을 당신이 쓴 것은 당신이 무엇을 의미하는지이라는 보풀 도구를 안심 :이 작업, 결과의 진리 값을 않습니다.

세 번째 용도는 논리 XOR 및 논리 XNOR을 생성하는 것입니다. C와 JavaScript 모두 a && b에서 논리 AND를 수행하고 (양측이 모두 true이면 true) a & b비트 AND를 수행합니다. a || b논리 OR을 수행하고 (적어도 하나이면 true) a | b비트 OR을 수행합니다. 로 비트 단위 XOR (배타적 OR)이 a ^ b있지만 논리 XOR에 대한 기본 제공 연산자가 없습니다 (정확히 한쪽이 true이면 true). 예를 들어, 사용자가 정확히 두 필드 중 하나에 텍스트를 입력하도록 할 수 있습니다. 당신이 할 수있는 일은 각각을 진실 값으로 변환하고 비교하는 것 !!x !== !!y입니다.



8

여기에 많은 훌륭한 답변이 있지만, 지금까지 읽으 셨다면, 이것이 제가 '얻는'데 도움이되었습니다. Chrome 등에서 콘솔을 열고 다음을 입력하십시오.

!(!(1))
!(!(0))
!(!('truthy')) 
!(!(null))
!(!(''))
!(!(undefined))
!(!(new Object())
!(!({}))
woo = 'hoo'
!(!(woo))
...etc, etc, until the light goes on ;)

당연히 이것들은 단순히 !! someThing을 입력하는 것과 동일하지만 추가 된 괄호는 더 이해하기 쉽게 만들 수 있습니다.


8

!!x 속기 Boolean(x)

첫 번째 뱅은 js 엔진을 강제로 실행 Boolean(x)하지만 값을 반전시키는 부작용이 있습니다. 따라서 두 번째 강타는 부작용을 취소합니다.


8

그것은 모든 것을 부울로 만듭니다.

예를 들면 다음과 같습니다.

console.log(undefined); // -> undefined
console.log(!undefined); // -> true
console.log(!!undefined); // -> false

console.log('abc'); // -> abc
console.log(!'abc'); // -> false
console.log(!!'abc'); // -> true

console.log(0 === false); // -> undefined
console.log(!0 === false); // -> false
console.log(!!0 === false); // -> true

7

이 질문은 매우 철저하게 답변되었지만 가능한 한 단순화되어 희망을 갖는 대답을 추가하고 싶습니다 !! 최대한 쉽게 파악할 수 있습니다.

javascript에는 "truthy"및 "falsey"값이 있기 때문에 다른 표현식에서 평가할 때 검사중인 값 또는 표현식이 실제로 true또는 그렇지 않은 경우에도 true 또는 false 조건을 초래하는 표현식이 있습니다 false.

예를 들어 :

if (document.getElementById('myElement')) {
    // code block
}

해당 요소가 실제로 존재하면 표현식은 true로 평가되고 코드 블록이 실행됩니다.

하나:

if (document.getElementById('myElement') == true) {
    // code block
}

... 실제 상태가 아니며 요소가 존재하더라도 코드 블록이 실행되지 않습니다.

왜? document.getElementById()if()명령문 에서 "true"식이 true로 평가 되기 때문에 실제 부울 값이 아닙니다 true.

이 경우 이중 "not"은 매우 간단합니다. 그것은 단순히 두 개의 not연속입니다.

첫 번째는 단순히 진실 또는 허위 값을 "반전"하여 실제 부울 유형을 생성 한 다음 두 번째는 원래의 상태로 다시 "반전"하지만 실제 부울 값으로 다시 되돌립니다. 그렇게하면 일관성이 있습니다.

if (!!document.getElementById('myElement')) {}

if (!!document.getElementById('myElement') == true) {}

예상대로 BOTH가 모두 true를 반환합니다.


7

나는 단지 그것을 추가하고 싶었다

if(variableThing){
  // do something
}

와 같다

if(!!variableThing){
  // do something
}

그러나 이것은 정의되지 않은 경우 문제가 될 수 있습니다.

// a === undefined, b is an empty object (eg. b.asdf === undefined)
var a, b = {};

// Both of these give error a.foo is not defined etc.
// you'd see the same behavior for !!a.foo and !!b.foo.bar

a.foo 
b.foo.bar

// This works -- these return undefined

a && a.foo
b.foo && b.foo.bar
b && b.foo && b.foo.bar

여기서의 트릭은 &&s 체인이 찾은 첫 번째 잘못된 값을 반환 하며 , if 문 등에 제공 될 수 있습니다. 따라서 b.foo가 정의되지 않은 경우 undefined를 반환하고 b.foo.bar명령문을 건너 뜁니다. 오류.

위의 수익률은 정의되지 않은하지만 당신은 빈 문자열, 거짓, NULL, 0이있는 경우, 그 값을 반환하고 우리가 체인에서는 이러한 문제가 발생할 곧 정의되지 않은 - []{}"truthy"모두 우리가 소위 "아래로 계속 && chain "오른쪽에있는 다음 값으로 이동하십시오.

추신 : 같은 일을하는 또 다른 방법은입니다 (b || {}).foo. 왜냐하면 b가 정의되지 않으면 다음 b || {}이 될 {}것입니다. "정의되지 않은"내의 값에 액세스하려고 시도하지 않고 빈 객체의 값에 액세스 할 것입니다 (오류 없음) (오류의 원인) ). 그래서, (b || {}).foo과 동일 b && b.foo((b || {}).foo || {}).bar동일하다 b && b.foo && b.foo.bar.


좋은 지적-내 대답을 변경했습니다. 당신이 말했듯이 때문 만이 깊은 세 가지 수준의 중첩있어 물체에 발생하는 ({}).anything줄 것이다undefined
라이언 테일러

5

이 위대한 답변을 모두 본 후을 사용하는 또 다른 이유를 추가하고 싶습니다 !!. 현재 Angular 2-4 (TypeScript)에서 일하고 있으며 false사용자가 인증되지 않은 것처럼 부울을 반환하려고 합니다. 인증되지 않은 경우 token-string은 null또는 ""입니다. 다음 코드 블록을 사용하여이 작업을 수행 할 수 있습니다.

public isAuthenticated(): boolean {
   return !!this.getToken();
}

4

다음은 각도 js의 코드입니다.

var requestAnimationFrame = $window.requestAnimationFrame ||
                                $window.webkitRequestAnimationFrame ||
                                $window.mozRequestAnimationFrame;

 var rafSupported = !!requestAnimationFrame;

그들의 의도는 requestAnimationFrame의 함수 가용성에 따라 rafSupported를 true 또는 false로 설정하는 것입니다.

일반적으로 다음과 같은 방법으로 확인하여 얻을 수 있습니다.

if(typeof  requestAnimationFrame === 'function')
rafSupported =true;
else
rafSupported =false;

짧은 길은 사용할 수 있습니다!

rafSupported = !!requestAnimationFrame ;

따라서 requestAnimationFrame에 함수가 할당되면! requestAnimationFrame은 false이고 하나 더 있습니다! 그것의 사실이다

requestAnimationFrame이 정의되지 않은 것으로 가정하면! requestAnimationFrame은 true이고 하나 더 있습니다! 그것의 거짓


3

JavaScript의 일부 연산자는 암시 적 유형 변환을 수행하며 때로는 유형 변환에 사용됩니다.

단항 !연산자는 피연산자를 부울로 변환하고 무효화합니다.

이 사실은 소스 코드에서 볼 수있는 다음 관용구로 이어집니다.

!!x // Same as Boolean(x). Note double exclamation mark


3

변수의 부울 값을 반환합니다.

대신 Boolean클래스를 사용할 수 있습니다.

(코드 설명을 읽으십시오)

var X = "test"; // X value is "test" as a String value
var booleanX = !!X // booleanX is `true` as a Boolean value beacuse non-empty strings evaluates as `true` in boolean
var whatIsXValueInBoolean = Boolean(X) // whatIsXValueInBoolean is `true` again
console.log(Boolean(X) === !!X) // writes `true`

즉, Boolean(X) = !!X사용 중입니다.

아래의 코드 스 니펫을 확인하십시오

let a = 0
console.log("a: ", a) // writes a value in its kind
console.log("!a: ", !a) // writes '0 is NOT true in boolean' value as boolean - So that's true.In boolean 0 means false and 1 means true.
console.log("!!a: ", !!a) // writes 0 value in boolean. 0 means false.
console.log("Boolean(a): ", Boolean(a)) // equals to `!!a`
console.log("\n") // newline

a = 1
console.log("a: ", a)
console.log("!a: ", !a)
console.log("!!a: ", !!a) // writes 1 value in boolean
console.log("\n") // newline

a = ""
console.log("a: ", a)
console.log("!a: ", !a) // writes '"" is NOT true in boolean' value as boolean - So that's true.In boolean empty strings, null and undefined values mean false and if there is a string it means true.
console.log("!!a: ", !!a) // writes "" value in boolean
console.log("\n") // newline

a = "test"
console.log("a: ", a) // writes a value in its kind
console.log("!a: ", !a)
console.log("!!a: ", !!a) // writes "test" value in boolean

console.log("Boolean(a) === !!a: ", Boolean(a) === !!a) // writes true

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.