JavaScript OR (||) 변수 할당 설명


351

이 JavaScript 스 니펫을 감안할 때 ...

var a;
var b = null;
var c = undefined;
var d = 4;
var e = 'five';

var f = a || b || c || d || e;

alert(f); // 4

누군가이 기술이 무엇인지 설명해 줄 수 있습니까? (최상의 추측은이 질문의 제목입니다!) 어떻게 / 왜 정확히 작동합니까?

내 이해는 변수에 fnull 또는 undefined가 아닌 값을 가진 첫 번째 변수의 가장 가까운 값 (왼쪽에서 오른쪽으로)이 할당되지만이 기술에 대한 많은 참조 자료를 찾지 못했음을 알고 있습니다. 많이 사용하는 것을 보았습니다.

또한이 기술은 JavaScript에만 해당됩니까? PHP에서 비슷한 작업을 수행 f하면 d자체 값이 아닌 실제 부울 값 이 생성된다는 것을 알고 있습니다.


4
오래된 질문이지만 PHP와 관련하여 사용할 수있는 구문이 있습니다 $f=$a or $f=$b or $f=$c; // etc. PHP는 동일한 작업을 수행하는 ||연산자와 연산자 를 모두 가지고 있습니다 or. 그러나 or평가 할당하는 동안이 ||되기 전에 평가된다. 이것은 또한 당신에게 멸망 스타일을 제공합니다$a=getSomething() or die('oops');
Manngo

1
PHP 5.3에서는 삼항 연산자의 중간 부분을 생략 할 수 있습니다. 또한 다음과 같이 조금 더 짧게자를 수도 있습니다. $f = $a ?: $b ?: $c;
Rei

1
PHP 7부터는 ??이것을 사용할 수 있습니다 . $a = $b ?? 'default'
스펜서 러스킨

@SpencerRuskin이므로 if $a의 값 이 true 로 지정됩니다 . $b$b'default'
oldboy

맞습니다. 이 페이지의 null 통합 연산자 섹션을보십시오 : php.net/manual/en/migration70.new-features.php
Spencer Ruskin

답변:


212

설명은 단락 평가 를 참조하십시오 . 이러한 연산자를 구현하는 일반적인 방법입니다. JavaScript에 고유하지 않습니다.


57
'gotcha'를 명심하십시오. 마지막은 모두 정의되지 않았거나 null 또는 false 인 경우에도 항상 할당됩니다. 체인 끝에서 알 수없는 것을 설정하는 것이 거짓, 널 또는 정의되지 않은 것은 아무것도 발견되지 않았다는 신호를 보내는 좋은 방법입니다.
Erik Reppen

나는이 기술을 몇 년 동안 보았지만, 그것을 사용하고 싶을 때 그때 나에게 타격을 준 것은 표현의 결과가 부울로 캐스팅되지 않는다는 것입니다. 나중에 할 수 없습니다 if( true == f ). 정수가 f에 저장된 경우이 테스트는 항상 false를 반환합니다.

9
실제로, 당신은 할 수 있습니다 . 이것은 테스트가 통과하는 if(true == f)것과 if(f)같습니다. 당신은 또한 테스트하려는 경우 유형 의를 f: 엄격한 비교를 사용 if(true === f), 참으로 실패합니다.
Alsciende

5
예, 단락 평가가 일반적입니다. 그러나 여기서 차이점은 JavaScript가 실행을 중단 한 마지막 값을 반환하는 방식에 있습니다. @ Anurag의 대답은 이것을 설명하는 데 훨씬 좋습니다.
Ben.12 December

그것이 초보자에게 가장 좋은 설명인지 확실하지 않습니다. 내가 추천 : javascript.info/logical-operators을
csguy

198

변수가 거짓 인 경우이 값을 기본값 으로 지정합니다 .yx

JavaScript의 부울 연산자는 피연산자를 반환 할 수 있으며 다른 언어와 같이 항상 부울 결과는 아닙니다.

논리 OR 연산자 ( ||)는 첫 번째 피연산자가 거짓이면 두 번째 피연산자의 값을 반환하고, 그렇지 않으면 첫 번째 피연산자의 값이 반환됩니다.

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

"foo" || "bar"; // returns "foo"
false || "bar"; // returns "bar"

Falsy 값에 그 누가 강제 변환됩니다 false부울 컨텍스트에서 사용할 때, 그들은이다 0, null, undefined, 빈 문자열, NaN물론을 false.


1
+1 그런 또 다른 연산자가 있습니까? 또는 ||독점적입니다.
OscarRyz

9
@Support (@Oscar) : 논리 &&연산자는 그 자체에 의해의 경우는 첫 번째 피연산자의 값을 반환 유사한 행동을 가지고 falsy 처음 인 경우에만, 그리고 두 번째 피연산자의 값을 반환 truthy , 예를 들어 ("foo" && "bar") == "bar"(0 && "bar") == 0
CMS

12
거짓 은 실제로 기술 용어입니다.
ChaosPandion

8
그래서 우리는이 글에서 ||, &&, "Falsy"와 "Truly"에 대해 배웠습니다. "숨겨진"선물로 최고의 답변.
Alex

4
@Alex NB : "Truthy"(! "Truly")
Bumpy

183

Javacript는 논리 연산자 및에 대해 단락 평가 를 사용합니다 . 그러나, 또는 대신 실행을 중단 한 마지막 값의 결과를 반환한다는 점에서 다른 언어와 다릅니다 .||&&truefalse

다음 값은 JavaScript에서 허위로 간주됩니다.

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

연산자 우선 순위 규칙을 무시하고 간단하게 유지하기 위해 다음 예제는 평가를 중단 한 값을 보여주고 결과로 반환됩니다.

false || null || "" || 0 || NaN || "Hello" || undefined // "Hello"

처음 5 개의 값 NaN은 허위이므로 첫 번째 진실한 값을 충족 할 때까지 왼쪽에서 오른쪽으로 모두 평가됩니다 "Hello". 전체 표현식이 사실이되므로 더 높은 값은 평가되지 않고 "Hello"표현식의 결과로 반환됩니다. . 마찬가지로이 경우 :

1 && [] && {} && true && "World" && null && 2010 // null

처음 5 개의 값은 모두 진실이며 첫 번째 잘못된 값 ( null)을 충족 할 때까지 식을 거짓으로 만들어 2010더 이상 평가되지 않으며 null식의 결과로 반환됩니다.

당신이 주신 예제는 JavaScript의이 속성을 사용하여 할당을 수행하는 것입니다. 일련의 값 중 첫 번째 진실 또는 허위 가치를 얻는 데 필요한 모든 곳에서 사용할 수 있습니다. 이 코드는 아래의 값을 할당합니다 "Hello"으로 b대신하는 경우 - 다른 검사를하고, 그것은 더 쉽게 기본 값을 할당 할 수있다.

var a = false;
var b = a || "Hello";

아래 예제를이 기능의 악용이라고 부를 수 있으며 코드를 읽기가 더 어렵다고 생각합니다.

var messages = 0;
var newMessagesText = "You have " + messages + " messages.";
var noNewMessagesText = "Sorry, you have no new messages.";
alert((messages && newMessagesText) || noNewMessagesText);

경고 내에서 우리 messages는 거짓 인지 확인 하고, 그렇다면, 평가하고 반환하고 noNewMessagesText, 그렇지 않으면 평가하고 반환 newMessagesText합니다. 이 예제에서는 거짓이므로 noNewMessagesText에서 멈추고 경고 "Sorry, you have no new messages."합니다.


36
이것은 다음과 같은 설명으로 인해 제 의견으로는 가장 좋은 답변입니다.However, it's different to other languages in that it returns the result of the last value that halted the execution, instead of a true, or false value.
mastazi

1
@mastazi Yep, 굵은 글꼴 IMHO로 이동해야합니다.
noober

6
답이되어야합니다. 테스트 사례에서 선택된 값을 보여줍니다.
Dadan

동의, 이것은 JavaScript 변수 할당 문제를 구체적으로 다루기 때문에 내가 가장 좋아하는 대답입니다. 또한 할당을 테스트하기 위해 (연산자 뒤) 후속 변수 중 하나로 삼항을 사용하기로 선택한 경우, 할당 평가가 제대로 작동하려면 삼항을 괄호로 묶어야합니다.
Joey T

이것은 정답이어야합니다
Alan

49

Javascript 변수는 입력되지 않으므로 f는 부울 연산자를 통해 할당 된 경우에도 정수 값을 할당 할 수 있습니다.

f 에 false아닌 가장 가까운 값이 할당됩니다 . 따라서 0, false, null, undefined가 모두 전달됩니다.

alert(null || undefined || false || '' || 0 || 4 || 'bar'); // alerts '4'

13
''이 경우에도 같은 거짓을 잊지 마십시오 .
Brigand

f is assigned the NEAREST value여기서 중요한 점 을 지적 해 주셔서 감사합니다 .
steviejay

3
"가장 가까운"은 그 모양이 있지만 사실이 아닙니다. 부울 ||연산자 인 부울 연산자에는 왼쪽과 오른쪽의 두 피연산자가 있습니다. 의 왼쪽 ||진리 인 경우 작업이 왼쪽으로 해석되고 오른쪽이 무시됩니다. 왼쪽이 falsy 이면 오른쪽으로 해석됩니다. 따라서 null || undefined || 4 || 0실제로 undefined || 4 || 0어느 것이 4 || 0무엇으로 해결되는지 확인합니다 4.
devios1

29

그것에 마법이 없습니다. 부울 식은 a || b || c || d느리게 평가됩니다. Interpeter는의 값을 찾고 a, 정의되지 않았으므로 false이므로 계속 진행 한 다음, b어느 것이 null인지, 여전히 잘못된 결과를 제공하여 계속 진행 한 다음 c동일한 이야기를 봅니다 . 마지막으로 d'응, null이 아니기 때문에 결과가 있습니다'라고보고 최종 변수에 지정합니다.

이 트릭은 부울 식의 지연 단락 평가를 수행하는 모든 동적 언어에서 작동합니다. 정적 언어에서는 컴파일되지 않습니다 (유형 오류). 부울 표현식을 평가하고자하는 언어에서는 논리 값을 반환합니다 (이 경우 true).


6
꽤 정적 인 언어 C #에서는 ?? 연산자 a la : 객체 f = a ?? b ?? 씨 ?? d ?? 이자형;
herzmeister

2
herzmeister-감사합니다! 나는 몰랐다 ?? 연산자는 C #으로 연결될 수 있고 게으른 평가 기법에 사용될 수 있습니다
Marek

3
다른 곳에서 언급했듯이, 그 마지막 d은 null / undefined인지 여부에 관계없이 지정됩니다.
BlackVegetable

약간의 수정 : ||왼쪽이 잘못되면 연산자는 항상 전체 오른쪽 피연산자로 해석됩니다. 부울 연산자이므로 왼쪽과 오른쪽의 두 가지 입력 만 볼 수 있습니다. 파서는 그것들을 일련의 용어로 보지 않기 때문에, 그 값이 다른 값의 왼쪽 피연산자가 아닌 한 첫 번째 진실 값을 찾으면 실제로 멈추지 않습니다 ||.
devios1

8

이 질문은 이미 몇 가지 좋은 답변을 받았습니다.

요약하면이 기술은 언어가 컴파일되는 방식의 기능을 활용하고 있습니다. 즉, JavaScript는 부울 연산자의 평가를 "단락"하여 첫 번째 거짓이 아닌 변수 값 또는 마지막 변수에 포함 된 값과 관련된 값을 반환합니다. 거짓으로 평가 될 값에 대한 Anurag의 설명을 참조하십시오.

이 기술을 사용하는 것은 여러 가지 이유로 좋은 습관이 아닙니다. 하나.

  1. 코드 가독성 : 부울 연산자를 사용하고 있으며이 컴파일 방식의 동작을 이해할 수없는 경우 예상 결과는 부울 값입니다.
  2. 안정성 : 여러 언어에서 일치하지 않는 언어가 컴파일되는 방식의 기능을 사용하고 있으며 이로 인해 향후 변경 될 가능성이 있습니다.
  3. 문서화 된 기능 :이 요구를 충족하고 더 많은 언어에서 일관된 기존 대안이 있습니다. 이것은 삼항 연산자입니다.

    ()? 값 1 : 값 2.

삼항 연산자를 사용하려면 조금 더 입력해야하지만 평가되는 부울 식과 할당되는 값을 명확하게 구분합니다. 또한 체인을 연결할 수 있으므로 위에서 수행 한 기본 할당 유형을 다시 만들 수 있습니다.

var a;
var b = null;
var c = undefined;
var d = 4;
var e = 'five';

var f =  ( a ) ? a : 
                ( b ) ? b :
                       ( c ) ? c :
                              ( d ) ? d :
                                      e;

alert(f); // 4

potentially be targeted for change in the future.예,하지만 자바 스크립트에는 적용되지 않습니다.
Dadan

여기에 와서 위의 모든 대답을 보았고 과제에 대해 무언가를 생각했습니다. 방금 Robert C Martin의 Clean Code를 읽었으며 이러한 유형의 과제는 "부작용 없음"규칙을 위반하는 것입니다. 저자 자신은 그의 책이 좋은 코드를 생성하는 많은 기술 중 하나 일 뿐이라고 말합니다. 아무도 이런 종류의 임무에 반대하는 사람이 없다는 것에 여전히 놀랐습니다. +1
Albert Rothman

답변 주셔서 감사합니다. 더 많은 사람들이 코드를 작성할 때 부작용을 고려해야한다고 생각하지만 다른 사람의 코드를 관리하는 데 많은 시간을 할애 할 때까지. 그들은 종종 그것을 고려하지 않습니다.
WSimpson

1
당신은 정말로 괴물이 더 명확하다고 생각 a || b || c || d || e합니까?
devios1

1
@AlbertRothman 부작용이 없습니다. 아무것도 변경되지 않습니다. null 병합에 대한 축약 형이며 많은 언어에서 매우 일반적인 기능입니다.
devios1

7

출력 첫 번째 true 값을 반환 합니다 .

모두 거짓이면 마지막 거짓 값을 반환합니다.

예:-

  null || undefined || false || 0 || 'apple'  // Return apple

4

새 변수 ( z)를 x"무결 한"값 (0이 아닌 값, 유효한 객체 / 배열 / 함수 / 무엇이든) 또는 y그렇지 않은 값으로 설정합니다. x존재하지 않는 경우 기본값을 제공하는 비교적 일반적인 방법입니다 .

예를 들어 선택적 콜백 매개 변수를 사용하는 함수가있는 경우 아무 것도 수행하지 않는 기본 콜백을 제공 할 수 있습니다.

function doSomething(data, callback) {
    callback = callback || function() {};
    // do stuff with data
    callback(); // callback will always exist
}

1

이 경우 것을 의미 x설정되고, 값이 z될 것이다 x그렇지 않으면, y그 값은로 설정 될 설정 z의 값.

그것은 같은

if(x)
  z = x;
else
  z = y;

JavaScript의 논리 연산자는 부울 값을 반환하지 않지만 작업을 완료하는 데 필요한 마지막 요소의 값 (OR 문장에서 첫 번째는 거짓이 아닌 값이되고 AND 문장에서 마지막이됩니다) 일 수 있습니다. ). 작업이 실패하면 false반환됩니다.


5
이것은 잘못이다! 만약 (x) {z = x; } else {z = y;} 첫 번째 값이 false이면 두 번째 값은 실제로 값이 무엇인지에 관계없이 항상 지정됩니다.
evilpie

x가 false 이면 y에 z를 할당한다고 생각합니다 . 그것은 FF에서 저에게 효과적입니다. 물론 구현에 따라 다를 수도 있습니다.
tvanfosson 2016 년

7
거짓 반환에 대한 마지막 부분은 사실이 아닙니다 (말장난 의도가 없음). 첫 번째 값이 거짓이면, ||연산자는 두 번째 값을 진실의 유무에 관계없이 반환합니다.
Matthew Crumley

-1. 동등한 코드 스 니펫은 정확하지만 중요한 점은 해당 값이 truezx경우 값으로 설정 된다는 것 입니다. 그렇지 않으면의 값으로 설정됩니다 y. 즉 x, 예를 들어 0또는 빈 문자열 로 설정된 경우 ""해당 값이 거짓 이므로 사용자가 말하는 것을 수행하지 않습니다 .
Daniel Cassidy

1

단락 연산자라고합니다.

단락 평가에 따르면 두 번째 인수는 첫 번째 인수가 식의 값을 결정하기에 충분하지 않은 경우에만 실행되거나 평가됩니다. OR (||) 함수의 첫 번째 인수가 true로 평가되면 전체 값이 true 여야합니다.

함수 인수의 기본값을 설정하는 데 사용될 수도 있습니다 .`

function theSameOldFoo(name){ 
  name = name || 'Bar' ;
  console.log("My best friend's name is " + name);
}
theSameOldFoo();  // My best friend's name is Bar
theSameOldFoo('Bhaskar');  // My best friend's name is Bhaskar`

0

X를 평가하고 X가 null이 아닌 경우 빈 문자열 또는 0 (논리적 거짓)이면 z에 할당합니다. X가 null, 빈 문자열 또는 0 (논리적 거짓)이면 y를 z에 할당합니다.

var x = '';
var y = 'bob';
var z = x || y;
alert(z);

'bob'을 출력합니다.


'빈'이라는 말의 의미를 명확히해야합니다. 빈 문자열은에 강제 false되지만 빈 배열 또는 객체는에 강제됩니다 true.
Daniel Cassidy

@Daniel "null, empty 또는 0"-배열 및 객체와 관련하여 null이 적용됩니다. 그래도 포인트를 가져갔습니다.
tvanfosson

0

Bill Higgins의 블로그 게시물 에 따르면 ; Javascript 논리 OR 할당 관용구 (2007 년 2 월),이 동작은 v1.2 이상 (최소)

그는 또 다른 용도 (인용구)를 제안한다 : " 크로스 브라우저 차이의 경량 정규화 "

// determine upon which element a Javascript event (e) occurred
var target = /*w3c*/ e.target || /*IE*/ e.srcElement;
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.