자바 스크립트 삼항 연산자를 사용한 연산자 우선 순위


116

이 코드의 첫 부분 (+ =)을 삼항 연산자와 함께 사용하여 머리를 감쌀 수 없습니다.

h.className += h.className ? ' error' : 'error'

이 코드가 작동한다고 생각하는 방식은 다음과 같습니다.

h.className = h.className + h.className ? ' error' : 'error'

그러나 내 콘솔에 오류가 발생하기 때문에 올바르지 않습니다.

그래서 내 질문은이 코드를 올바르게 인터펫해야합니까?

답변:


141
h.className = h.className + (h.className ? ' error' : 'error')

운영자가에서 일하기를 원하고 이에 h.className대해 더 구체적으로 설명하십시오.
물론 해를 끼쳐서는 안됩니다. h.className += ' error' 이는 또 다른 문제입니다.

또한 +삼항 연산자보다 우선합니다. JavaScript 연산자 우선 순위


3
나는에서 해를 끼칠 수는 없지만 h.className += ' error'처음에 비어있는 경우 문자열 시작 부분에 공백을 남깁니다. 삼항 연산의 요점은 깔끔한 문자열을 만드는 것입니다.
JMTyler 2011 년

@JMTyler-그게 정확히 내가 표시 한 것입니다-처음부터 공백을 유지하기 위해 모든 것이 완료 되었다면 그만한 가치가 없습니다. (가장자리 케이스에는 정확한 jQuery 또는 XPath 선택기가 포함됩니다). 어쨌든 감사합니다.
코비

@Kobi +1 오퍼레이터 우선 경고 만!
Ed Chapel

129

다음과 같이 생각하십시오.

<variable> = <expression> ? <true clause> : <false clause>

명령문이 실행되는 방식은 기본적으로 다음과 같습니다.

  1. 않습니다 <expression>참으로 평가 거짓으로 평가합니까?
  2. 만약 <expression>평가하여 true로, 다음의 값 <true clause>에 할당은 <variable>, <false clause>무시하고, 다음 명령문이 실행됩니다.
  3. <expression>false로 평가 되면 <true clause>무시되고의 값이 <false clause>에 할당됩니다 <variable>.

이 언어와 다른 언어에서 삼항 연산자로 깨달아야 할 중요한 것은 어떤 코드가 <expression>평가 될 때 true 또는 false 중 하나의 부울 결과를 생성해야한다는 것입니다.

귀하의 예제의 경우 내 설명에서 "assigned to"를 "added to"로 바꾸거나 사용중인 속기 산술에 대해 유사합니다.


완전한 주석이 적절한 지 확인하십시오. :) 왼쪽 표현식이 먼저 "함께 그룹화"된 이유에 대한 설명을 건너 뜁니다 (즉 +, 조건 / 삼항 연산자보다 우선 순위가 높기 때문입니다 (사실 조건 연산자는 거의 항상 마지막 것입니다). ) 어떤 식으로 평가 하였다.
코딩 사라

10

+=원하는대로 수행하지만 오른쪽에있는 h.className삼 항문에서 거짓인지 확인하고 정의되지 않은 경우 확인합니다. 사실이라면 (즉, 클래스 이름이 이미 지정되어있는 경우) 공백과 함께 오류가 추가되고 (즉, 클래스 추가 ), 그렇지 않으면 공백없이 추가됩니다.

제안한대로 코드를 다시 작성할 수 있지만 h.className삼항 연산자에서 실제 값을 사용하는 대신 진실성 비교에 사용할 코드를 지정해야 하므로 값의 연결에 신경 쓰지 마십시오. 삼항 연산을 수행하는 동시에 :

h.className = h.className + (h.className ? ' error' : 'error');

13
그래, 거짓undefined 이 아니에요 그것은 마치
그랬던

4

=연산자 의 오른쪽 은 왼쪽에서 오른쪽으로 평가됩니다. 그래서,

g.className = h.className + h.className ? ' error' : 'error';`

다음과 같다

h.className = (h.className + h.className) ? ' error' : 'error';

동등하다

h.className += h.className ? ' error' : 'error';

삼 항문을 괄호로 구분해야합니다.

h.className = h.className + (h.className ? ' error' : 'error');

3
if (h.className) {
    h.className = h.className + ' error';
} else {
    h.className = h.className + 'error';
}

다음과 동일해야합니다.

h.className += h.className ? ' error' : 'error';

1

나는 이것이 매우 오래된 질문이라는 것을 알고 있지만, 모두 불완전 해 보이는 답에 100 % 만족하지 않습니다. 그래서 우리는 첫 번째 교장에서 다시 시작합니다.

사용자의 전반적인 목표 :

코드 요약 : " error문자열에 이미 클래스 이름이있는 경우 선택적으로 선행 공백을 사용하여 문자열에 클래스 이름 을 추가하고 싶습니다 ."

가장 간단한 솔루션

Kobi가 5 년 전에 지적했듯이 클래스 이름에 선행 공백이 있으면 알려진 브라우저에 문제가 발생하지 않으므로 실제로 가장 짧은 올바른 해결책은 다음과 같습니다.

h.className += ' error';

즉, 있었어야 실제 답변을 받는 실제 문제 .


그럴 수도 있지만 질문은 ...

1) 왜 이것이 효과가 있었습니까?

h.className += h.className ? ' error' : 'error'

조건 / 삼항 연산자는 true또는 결과를 할당하는 if 문처럼 작동합니다.false 는 변수 경로 합니다.

코드는 다음과 같이 평가되기 때문에 작동했습니다.

if (h.className IS NOT null AND IS NOT undefined AND IS NOT '') 
    h.className += ' error'
else
    h.className += 'error'

2) 왜 이것이 깨졌습니까?

h.className = h.className + h.className ? ' error' : 'error'

이 질문에는 "내 콘솔에 [n] 오류가 발생합니다."라는 메시지가 표시되어 코드 가 작동하지 않는다고 오해 할 수 있습니다 . 실제로 다음 코드는 error 없이 실행 되지만 문자열 비어 있지 않으면 'error'를 반환하고 문자열 비어 있어 요구 사항을 충족하지 않으면 'error'를 반환합니다. .

그 코드는 항상에만 포함 된 문자열 결과 ' error'또는 'error'그이 의사 코드로 평가되므로 :

if ((h.className + h.className) IS NOT null AND IS NOT undefined AND IS NOT '')
    h.className = ' error'
else
    h.className = 'error'

그 이유는 더하기 연산자 ( +일반인에게)가 조건 / 삼항 연산자 (15)보다 "우선 순위"(6)가 더 높기 때문입니다. 숫자가 거꾸로 나타나는 걸 알아

우선 순위는 단순히 언어의 각 연산자 유형이 특정 사전 정의 된 순서로 평가된다는 것을 의미합니다 (왼쪽에서 오른쪽이 아닌).

참조 : 자바 스크립트 연산자 우선 순위

평가 순서를 변경하는 방법 :

이제 우리는 그것이 실패하는 이유를 알았습니다. 당신은 그것을 작동시키는 방법을 알아야합니다.

다른 답변 은 우선 순위 변경에 대해 이야기 하지만 그럴 수 없습니다 . 우선 순위는 언어에 고정되어 있습니다. 이것은 고정 된 규칙 집합 일뿐입니다. 그러나 평가 순서를 변경할 수 있습니다 .

평가 순서를 변경할 수있는 도구 상자의 도구 는 그룹화 연산자 (일명 대괄호)입니다. 이는 대괄호 외부의 연산 전에 대괄호의식이 평가되도록함으로써 수행됩니다. 그게 그들이하는 전부지만 충분합니다.

대괄호는 (그룹화 연산자) 다른 모든 연산자보다 우선 순위높기 때문에 작동합니다 ( "이제 레벨 0이 있습니다").

단순히 대괄호를 추가 하면 간단한 문자열 연결 전에 조건부 테스트가 먼저 수행되도록 평가 순서변경합니다 .

h.className = h.className + (h.className ? ' error' : 'error')

나는 이제 다른 사람들 사이에서 보이지 않는 녹에 대한이 대답을 남겨 둘 것입니다 :)


1

웨인에 대한 설명을 선택하고 싶습니다.

<variable> = <expression> ? <true clause> : <false clause>

두 가지 경우를 모두 고려해 보겠습니다.

case 1:
h.className += h.className ? 'true' : 'false'     
  • 할당 연산자가 잘 작동하고 값이 추가됩니다.
  • 처음 실행할 때 o / p : false
  • 두 번째. o / p : falsetrue-값이 계속 추가됨

case2 : h.className = h.className + h.className? '허위 사실'

  • 결과는 사례 1과 동일하지 않습니다.
  • 처음 실행할 때 o / p : false
  • 두 번째. o / p : false-값이 계속 추가되지 않습니다.

explanation

위의 코드에서 사례 1은 정상적으로 작동합니다.

반면 case2 :

h.className = h.className + h.className ? 'true' : 'false'
is executed as 
 h.className = (h.className + h.className) ? 'true' : 'false'

h.className + h.className=> 삼항 연산자가 더 높은 우선 순위를 갖기 때문에 삼항 연산자에 대한 표현식으로 간주됩니다. 따라서 항상 삼항 표현식의 결과가 할당됩니다.

대괄호를 사용하여 우선 순위를 정의해야합니다.

케이스 2가 케이스 1로 작동하려면 대괄호를 사용하여 고려할 평가 순서를 정의해야합니다.

h.className = h.className + (h.className ? ' error' : 'error') 

1
여기서 용어는 옳지 않습니다. 우선 순위는 언어에 내재되어 있으며 정의 하지 않습니다 . 대신 대괄호를 사용 하여 평가 순서 를 정의합니다 (다른 모든 연산자보다 우선 순위가 높음).
Gone Coding

@TrueBlueAussie 동의합니다. 내가 의도 읽기 +1에 대한 감사
Angelin Nadar
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.