구조 x = x || 당신은 의미합니까?


250

JavaScript를 디버깅하고 있는데 이것이 무엇을하는지 설명 할 수 ||없습니까?

function (title, msg) {
  var title = title || 'Error';
  var msg   = msg || 'Error on Request';
}

누군가 나에게 힌트를 줄 수 있습니까, 왜이 남자가 사용하고 var title = title || 'ERROR'있습니까? 때로는 var선언 없이도 볼 수 있습니다.


44
사람들은 이미이 대답 ...하지만 첫 번째 값 인 경우 두 번째 값이 선택되어 있다는 사실을 매우 유의 한 falsy뿐만 아니라, undefined. 내가 본 횟수 doWeDoIt = doWeDoIt || true는 나를 울리기에 충분합니다. (즉 doWeDoIt이제는되지 않을 것입니다 false)
Matt


4
C # 경험이있는 사람의 경우 이중 파이프 연산자는 null-coalesce 연산자와 같습니다 ??. 자바 스크립트는 null이 아닌 객체를 평가 처럼 true (또는 더 나은 evalualtes false로 객체를 null)
USR-로컬 ΕΨΗΕΛΩΝ

3
기분 나빠하지 마십시오-JS는이 끔찍한 코딩을 허용하는 유일한 구피 언어입니다 .... 모든 코드를 코드 라인에 중첩시키고 버려서 두 번째로 일회용으로 사용할 수 없게 만드는 것이 적절하다는 것을 가르치는 것입니다. :) 나는 30 년 동안 코딩을 시작했고 오래 전에 JS를 만지지 않았다. 내가 말할 수있는 모든 고통은 "상식이 이해가되지 않는다 .JS에만있다"cheetsheet 편리하다. 에 의해 입수! :)
Collin Chaffin

1
허용 된 답변을 내 답변으로 변경해보십시오 .
Michał Perłakowski

답변:


210

title인수가 선택 사항 임을 의미합니다 . 따라서 인수없이 메소드를 호출하면 기본값이 사용됩니다 "Error".

다음과 같이 작성하십시오.

if (!title) {
  title = "Error";
}

부울 표현식이있는 이러한 속기 트릭은 Perl에서도 일반적입니다. 표현으로 :

a OR b

이 평가에 true경우 중 하나 a또는 b이다 true. 따라서 a사실이라면 전혀 확인할 필요가 없습니다 b. 이를 단락 부울 평가라고합니다.

var title = title || "Error";

기본적으로로 title평가 되는지 확인합니다 false. 그것은, 그것은 "반환"않는 경우 "Error", 그렇지 않으면 반환합니다 title.


3
까다롭게 죄송하지만 인수는 선택 사항이 아닙니다. 인수는 점검됩니다
themightybun

4
이것은 대답이 아니며 선택 사항이 아닌 마지막 의견에 동의합니다. Perl 문이 실제로 SENSE를 만들고 완전히 다른 방식으로 평가되므로이 답변의 어느 부분도 Perl 참조조차 정확하지 않습니다. JS는 훨씬 더 "변환 된"부울 논리 방법으로 평가되어 읽기 / 쓰기에 훨씬 더 혼란 스럽다. 아래의 "더블 파이프 연산자 란 무엇입니까?"라는 제목의 대답은 실제로 정답입니다.
Collin Chaffin

198

이중 파이프 연산자 ( ||) 란 무엇입니까 ?

이중 파이프 연산자 ( ||)는 논리 OR연산자 입니다. 에서 대부분의 언어 는 다음과 같은 방식으로 작동합니다 :

  • 첫 번째 값이 false인 경우 두 번째 값을 확인합니다. 이면을 true반환 true하고이면 false을 반환합니다 false.
  • 첫 번째 값이 true인 경우 true두 번째 값이 무엇이든 항상를 반환합니다 .

따라서 기본적으로 다음과 같이 작동합니다.

function or(x, y) {
  if (x) {
    return true;
  } else if (y) {
    return true;
  } else {
    return false;
  }
}

여전히 이해가되지 않으면 다음 표를보십시오.

      | true   false  
------+---------------
true  | true   true   
false | true   false  

다시 말해, 두 값이 모두 거짓 인 경우에만 거짓입니다.

JavaScript에서 어떻게 다른가요?

JavaScript는 형식느슨 하기 때문에 약간 다릅니다 . 이 경우 ||부울이 아닌 값으로 연산자를 사용할 수 있습니다 . 의미가 없지만이 연산자를 함수 및 객체와 같이 사용할 수 있습니다.

(function(){}) || {}

거기서 무슨 일이?

값이 부울이 아닌 경우 JavaScript는 암시 적으로 boolean으로 변환합니다 . 이 값이 falsey 경우 (예 것을 의미한다 0, "", null, undefined(참조 자바 스크립트의 모든 falsey 값 , 그것으로 처리 될 것이다)) false; 그렇지 않으면로 취급됩니다 true.

true빈 함수가 진실이기 때문에 위의 예제는을 제공해야합니다 . 글쎄요. 빈 함수를 반환합니다. ||처음에 작성한대로 JavaScript 연산자가 작동하지 않기 때문 입니다. 다음과 같은 방식으로 작동합니다.

  • 첫 번째 값이 false 이면 두 번째 값을 반환 합니다 .
  • 첫 번째 값이 정확한 경우 첫 번째 값 을 반환 합니다 .

놀랐나요? 실제로, 그것은 전통적인 ||연산자 와 "호환"됩니다 . 다음 함수로 작성 될 수 있습니다.

function or(x, y) {
  if (x) {
    return x;
  } else {
    return y;
  }
}

로 true 값을 전달하면 true 값을 x반환 x합니다. 따라서 나중에 if절 에서 사용하면 :

(function(x, y) {
  var eitherXorY = x || y;
  if (eitherXorY) {
    console.log("Either x or y is truthy.");
  } else {
    console.log("Neither x nor y is truthy");
  }
}(true/*, undefined*/));

당신은 얻을 "Either x or y is truthy.".

경우 xfalsey이었다 eitherXorY될 것이다 y. 이 경우 "Either x or y is truthy."if y는 진실한 것입니다. 그렇지 않으면 당신은 얻을 "Neither x nor y is truthy"것이다.

실제 질문

이제 ||운영자의 작동 방식을 알면 x = x || y의미 하는 바를 스스로 알아낼 수 있습니다 . 경우 xtruthy이며, x할당되어 x있으므로 실제로 아무 일도 일어나지 않는다; 그렇지 않으면 y에 할당됩니다 x. 일반적으로 함수에서 기본 매개 변수를 정의하는 데 사용됩니다. 그러나, 종종 간주됩니다 나쁜 프로그래밍 연습 그것이 falsey 값을 (필요하지 않은 통과를 방지하기 때문에, undefined또는 null매개 변수로). 다음 예제를 고려하십시오.

function badFunction(/* boolean */flagA) {
  flagA = flagA || true;
  console.log("flagA is set to " + (flagA ? "true" : "false"));
}

첫눈에 유효 해 보입니다. 당신이 전달 된 경우, 어떤 일이 일어날 것 false같은 flagA(그것의 부울 이후, 즉 할 수있는 매개 변수 truefalse)? 될 것 true입니다. 이 예에서 설정하는 방법이 없습니다 flagAfalse.

명시 적으로 여부를 확인하기 위해 더 좋은 생각이 될 것 flagA입니다 undefined그렇게 :

function goodFunction(/* boolean */flagA) {
  flagA = typeof flagA !== "undefined" ? flagA : true;
  console.log("flagA is set to " + (flagA ? "true" : "false"));
}

더 길지만 항상 작동하며 이해하기 쉽습니다.


기본 함수 매개 변수에 ES6 구문을 사용할 수도 있지만 IE와 같은 이전 브라우저에서는 작동하지 않습니다. 이러한 브라우저를 지원하려면 Babel을 사용 하여 코드를 변환해야합니다 .

MDN의 논리 연산자를 참조하십시오 .


13
+1-가장 정확하고 완전한 답변. 그리고,이 질문을 가진 사람들 (JS를 처음 접하는 베테랑 코더들 중 일부는)은이 줄에서이 전체 답변의 가장 많은 부분에 초점을 두어야합니다. 그것없이 자란 사람들에게 우리에게있어 부울 연산자는 단지 그뿐입니다 ....... 그리고 코드를 읽거나 쓰는 동안 부울이 아닌 값을 부울로 변환하는 것을 멈추고 생각하는 것이 좋은 생각이라면 누구든지 그날 약을 복용하는 것을 잊었다! :)
Collin Chaffin

2
+1, 요컨대 : title = title || 'Error'수단if (title) { title = title; } else { title = 'Error'; }
앙드레 Elrico

나는 실제로 "그것은 말이되지 않지만"줄에 동의하지 않습니다. 예를 들어 라인이 C로 컴파일되지 않는다는 것을 알고 있지만 루비 또는 그루비에서 온 경우 잘 이해됩니다. 루비에서는로 표현할 수 title ||= 'Error'있습니다.
Elliot Nelson 5

28

제목이 설정되어 있지 않으면 'ERROR'를 기본값으로 사용하십시오.

더 일반적인 :

var foobar = foo || default;

읽는다 : foobar를 foo또는로 설정하십시오 default. 이것을 여러 번 연결할 수도 있습니다.

var foobar = foo || bar || something || 42;

1
변수의 이름이 같기 때문에 혼란 스럽습니다. 그들이하지 않을 때 훨씬 쉽습니다.
Norbert Norbertson 2016 년

14

이것을 조금 더 설명하면 ...

||오퍼레이터는 logical-이다 or연산자. 첫 번째 부분이 참이면 결과는 true이고 두 번째 부분이 참이면 참이고 두 부분이 참이면 참입니다. 명확성을 위해 여기에 테이블이 있습니다.

 X | Y | X || Y 
---+---+--------
 F | F |   F    
---+---+--------
 F | T |   T    
---+---+--------
 T | F |   T    
---+---+--------
 T | T |   T    
---+---+--------

이제 여기에 뭔가가 있습니까? 경우 X사실, 결과는 항상 true입니다. 우리가 그 X사실 을 안다면 전혀 확인할 필요가 없습니다 Y. 따라서 많은 언어에서 논리적 or(및 and다른 방향에서 논리적)에 대한 "단락"평가기를 구현 합니다. 그들은 첫 번째 요소를 확인하고 그것이 사실이라면 두 번째 요소를 전혀 확인하지 않아도됩니다. 결과 (논리적 용어로)는 동일하지만 실행 측면에서 두 번째 요소가 계산 비용이 높으면 큰 차이가있을 수 있습니다.

이것이 당신의 예와 어떤 관련이 있습니까?

var title   = title || 'Error';

그것을 보자. title요소는 함수에 전달됩니다. JavaScript에서 매개 변수를 전달하지 않으면 기본값은 null 값입니다. 또한 JavaScript에서 변수가 null 값이면 논리 연산자에 의해 false로 간주됩니다. 따라서이 함수가 주어진 제목으로 호출되면 거짓이 아닌 값이므로 로컬 변수에 할당됩니다. 그러나 값이 제공되지 않으면 널값이므로 false입니다. or그런 다음 논리 연산자는 두 번째 식을 평가하고 대신 'Error'를 반환합니다. 이제 지역 변수에 'Error'값이 지정되었습니다.

이것은 JavaScript에서 논리식을 구현하기 때문에 작동합니다. 그것은 적절한 부울 값을 반환 (하지 않습니다 true또는 false) 대신이 동등 간주 것과 같은 몇 가지 규칙에 따라 주어진 값 반환 true과 동등 무엇을 간주을 false. 부울 컨텍스트에서 JavaScript가 참 또는 거짓으로 간주하는 것을 배우려면 JavaScript 참조를 찾아보십시오.


8

이중 파이프는 논리적 "OR"을 나타냅니다. 다음과 같은 코드가있는 경우 자바 스크립트에서 엄격하게 설정되므로 "매개 변수가 설정되지 않은"경우에는 실제로 해당되지 않습니다.

function foo(par) {
}

그런 다음 전화

foo()
foo("")
foo(null)
foo(undefined)
foo(0)

동일하지 않습니다.

이중 파이프 (||)는 첫 번째 인수를 부울로 캐스트하고 결과 부울이 true 인 경우 지정을 수행하십시오. 그렇지 않으면 올바른 부분이 지정됩니다.

설정되지 않은 매개 변수를 확인하면 문제가됩니다.

선택적 매개 변수가 하나 인 함수 setSalary가 있다고 가정 해 봅시다. 사용자가 매개 변수를 제공하지 않으면 기본값 10을 사용해야합니다.

다음과 같이 확인하면 :

function setSalary(dollars) {
    salary = dollars || 10
}

이것은 호출시 예기치 않은 결과를 줄 것입니다

setSalary(0) 

위에서 설명한 흐름에 따라 여전히 10을 설정합니다.


8

기본적으로 || 이전의 값인지 확인합니다. true 인 경우 true로 평가되며, 해당되는 경우이 값을 사용하고 그렇지 않은 경우 || 뒤에 값을 사용합니다.

|| 다음에 값을 가져 오는 값 (내가 기억하기로는):

  • 찾으시는 주소가 없습니다
  • 그릇된
  • 0
  • ''(널 또는 널 문자열)

1
거짓 || null || 정의되지 않은 || 0 || ''|| '널 잊어 버렸습니다'
Dziamid

7

Cletus의 대답 은 정확 하지만 JavaScript에서 "false로 평가"하는 것과 관련하여 더 자세한 내용을 추가해야한다고 생각합니다.

var title = title || 'Error';
var msg   = msg || 'Error on Request';

title / msg가 제공되었는지 여부뿐만 아니라 둘 중 하나가 거짓인지 확인 합니다. 즉 다음 중 하나입니다.

  • 그릇된.
  • 0 (영)
  • ""(빈 문자열)
  • 없는.
  • 찾으시는 주소가 없습니다.
  • NaN (숫자가 아님을 의미하는 특수 숫자 값!)

그래서 라인에서

var title = title || 'Error';

제목이 정확하지 않은 경우 (즉, 거짓이 아니므로 title = "titleMessage"등) 부울 OR (||) 연산자는 하나의 'true'값을 찾았습니다. 이는 true로 평가되므로 단락되고 반환됩니다. 실제 값 (제목)

title이 거짓 인 경우 (즉, 위 목록 중 하나) 부울 OR (||) 연산자는 'false'값을 찾았으며 이제는 연산자의 다른 부분 인 'Error'를 평가해야합니다. 따라서 반환됩니다.

연산자의 양쪽이 모두 거짓으로 평가되면 (일부 빠른 방화 콘솔 실험 후) 보일 것입니다. 두 번째 '거짓'연산자를 반환합니다.

return ("" || undefined)

undefined를 반환하면 기본 제목 / 메시지를 ""(으)로 설정하려고 할 때이 질문에 대한 동작을 사용할 수 있습니다. 즉, 실행 후

var foo = undefined
foo = foo || ""

foo는 ""로 설정됩니다


5

이중 파이프 연산자

이 예가 유용한가요?

var section = document.getElementById('special');
if(!section){
     section = document.getElementById('main');
}

또한 될 수 있습니다

var section = document.getElementById('special') || document.getElementById('main');

4

앞서 언급 한 모든 사람들에게 설명을 더하기 위해 논리적 개념을 이해하기위한 몇 가지 예를 들겠습니다.

var name = false || "Mohsen"; # name equals to Mohsen
var family = true || "Alizadeh" # family equals to true

왼쪽이 실제 명령문으로 평가되면 완료되고 왼쪽이 리턴되어 변수에 지정됩니다. 다른 경우에는 오른쪽이 반환되어 할당됩니다.

그리고 연산자는 아래와 같은 반대 구조를 가지고 있습니다.

var name = false && "Mohsen" # name equals to false
var family = true && "Alizadeh" # family equals to Alizadeh

3

|| 부울 OR 연산자입니다. 자바 스크립트에서와 같이 undefined, null, 0, false잘못된 값 으로 간주 됩니다.

그것은 단순히 의미

true || true = true
false || true = true
true || false = true
false || false = false

undefined || "value" = "value"
"value" || undefined = "value"
null || "value" = "value"
"value" || null = "value"
0 || "value" = "value"
"value" || 0 = "value"
false || "value" = "value"
"value" || false = "value"

2

인용구 : "구문 x = x || y의 의미는 무엇입니까?"

기본값을 지정합니다.

이것은 x가 여전히 값을 기다리고 있지만 아직받지 않았거나 기본값으로 돌아 가기 위해 의도적으로 생략 된 경우를 대비 하여 기본값 y를 x로 제공하는 것을 의미 합니다 .


그것이 구조의 정확한 의미와 그것의 유일한 의미입니다. 또한 프로토 타입, 독립형 함수로 가져올 수있는 함수를 작성하는 서브 루틴, 다른 요소에 적용 할 빌린 메소드로도 사용되었습니다. 주요한 유일한 임무는 대상의 참조를 수정하는 것이 었습니다. 예 : function getKeys(x) { x = x || this ; .... }독립형 함수, 프로토 타입의 속성 메소드 및 다른 요소를`[element] .getKeys (anotherElement); '와 같은 인수로 가져올 수있는 요소의 메소드로 수정하지 않고 사용할 수 있습니다.
Bekim Bacaj

-5

그리고 한 가지 더 추가해야합니다.이 속기는 약간 혐오입니다. 할당을 제어하기 위해 우발적 인 인터프리터 최적화를 사용합니다 (첫 번째 작업이 진실 인 경우 두 번째 작업을 방해하지 않음). 그 사용은 운영자의 목적과 관련이 없습니다. 나는 그것이 사용되어야한다고 생각하지 않습니다.

초기화를 위해 삼항 연산자를 선호합니다.

var title = title?title:'Error';

이것은 올바른 목적으로 한 줄 조건부 연산을 사용합니다. 그것은 여전히 ​​진실로 보이지 않는 게임을하지만, 그것은 당신을위한 자바 스크립트입니다.

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