--- title: 연산자 우선순위 slug: Web/JavaScript/Reference/Operators/Operator_Precedence tags: - JavaScript - Operator - 연산자 - 우선순위 translation_of: Web/JavaScript/Reference/Operators/Operator_Precedence original_slug: Web/JavaScript/Reference/Operators/연산자_우선순위 ---
연산자 우선순위는 연산자를 실행하는 순서를 결정합니다. 우선순위가 높은 연산자가 먼저 실행됩니다.
아래와 같이 표현할 수 있는 표현식을 생각해 봅시다. 연산자1과 연산자2의 자리에는 아무 연산자를 넣을 수 있습니다.
a 연산자1 b 연산자2 c
두 연산자의 우선순위(아래 표 참조)가 다를 경우, 우선순위가 높은 연산자가 먼저 실행되고 결합성은 영향을 미치지 않습니다. 아래 예제에서는 덧셈이 곱셈보다 먼저 쓰였음에도 곱셈의 우선순위가 높기 때문에 먼저 실행됩니다.
console.log(3 + 10 * 2); // 23을 출력 console.log(3 + (10 * 2)); // 23을 출력, 괄호는 불필요함 console.log((3 + 10) * 2); // 26을 출력, 괄호로 인해 실행 순서가 바뀜
좌결합성(왼쪽에서 오른쪽으로)은 표현식이 (a 연산자1 b) 연산자2 c와 같이, 우결합성(오른쪽에서 왼쪽으로)은 a 연산자1 (b 연산자2 c)와 같이 계산된다는 의미입니다. 대입 연산자는 우결합성이므로 다음과 같은 코드를 작성할 수 있습니다.
a = b = 5; // a = (b = 5);와 같음
이때 대입 연산자는 대입된 값을 반환하므로 a와 b의 값이 5가 됨을 예상할 수 있습니다. 우선 b의 값이 5로 설정되고, 그 다음에는 a의 값이 우변인 b = 5의 반환값 5로 설정됩니다.
다른 예시로, 좌결합성인 다른 산술 연산자와 달리 거듭제곱 연산자 (**)만은 우결합성입니다. 흥미로운 점으로 표현식의 평가는 결합성과 무관하게 항상 왼쪽에서 오른쪽으로 진행됩니다.
| 코드 | 출력 |
function echo(name, num) {
console.log(name + " 항 평가함");
return num;
}
// 나눗셈 연산자 (/)에 주목
console.log(echo("첫째", 6) / echo("둘째", 2));
|
첫째 항 평가함 둘째 항 평가함 3 |
function echo(name, num) {
console.log(name + " 항 평가함");
return num;
}
// 거듭제곱 연산자 (**)에 주목
console.log(echo("첫째", 2) ** echo("둘째", 3));
|
첫째 항 평가함 둘째 항 평가함 8 |
여러 연산자의 우선순위가 같을 때는 결합성을 고려합니다. 위에서와 같이 연산자가 하나이거나 연산자끼리 우선순위가 다를 경우에는 결합성이 결과에 영향을 미치지 않습니다. 아래의 예제에서 같은 종류의 연산자를 여러 번 사용했을 때 결합성이 결과에 영향을 미치는 것을 확인할 수 있습니다.
| 코드 | 출력 |
function echo(name, num) {
console.log(name + " 항 평가함");
return num;
}
// 나눗셈 연산자 (/)에 주목
console.log(echo("첫째", 6) / echo("둘째", 2) / echo("셋째", 3));
|
첫째 항 평가함 둘째 항 평가함 셋째 항 평가함 1 |
function echo(name, num) {
console.log(name + " 항 평가함");
return num;
}
// 거듭제곱 연산자 (**)에 주목
console.log(echo("첫째", 2) ** echo("둘째", 3) ** echo("셋째", 2));
|
첫째 항 평가함 둘째 항 평가함 셋째 항 평가함 512 |
function echo(name, num) {
console.log(name + " 항 평가함");
return num;
}
// 첫 번째 거듭제곱 연산자 주변의 괄호에 주목
console.log((echo("첫째", 2) ** echo("둘째", 3)) ** echo("셋째", 2));
|
첫째 항 평가함 둘째 항 평가함 셋째 항 평가함 64 |
위의 예제에서 나눗셈은 좌결합성이므로 6 / 3 / 2는 (6 / 3) / 2와 같습니다. 한편 거듭제곱은 우결합성이므로 2 ** 3 ** 2는 2 ** (3 ** 2)와 같습니다. 그러므로 (2 ** 3) ** 2는 괄호로 인해 실행 순서가 바뀌기 때문에 위 표와 같이 64로 평가됩니다.
우선순위는 결합성보다 항상 우선하므로, 거듭제곱과 나눗셈을 같이 사용하면 나눗셈보다 거듭제곱이 먼저 계산됩니다. 예를 들어 2 ** 3 / 3 ** 2는 (2 ** 3) / (3 ** 2)와 같으므로 0.8888888888888888로 계산됩니다.
3 > 2 && 2 > 1 // true를 반환 3 > 2 > 1 // 3 > 2는 true인데, 부등호 연산자에서 true는 1로 변환되므로 // true > 1은 1 > 1이 되고, 이는 거짓이다. // 괄호를 추가하면 (3 > 2) > 1과 같다.
다음 표는 우선순위 내림차순(21부터 1까지)으로 정렬되어 있습니다.
| 우선순위 | 연산자 유형 | 결합성 | 연산자 |
|---|---|---|---|
| 21 | {{jsxref("Operators/Grouping", "그룹", "", 1)}} | 없음 | ( … ) |
| 20 | {{jsxref("Operators/Property_Accessors", "멤버 접근", "#점_표기법", 1)}} | 좌결합성 | … . … |
| {{jsxref("Operators/Property_Accessors", "계산된 멤버 접근","#괄호_표기법", "1")}} | 좌결합성 | … [ … ] |
|
| {{jsxref("Operators/new","new")}} (매개변수 리스트 존재) | 없음 | new … ( … ) |
|
| 좌결합성 | … ( … ) |
||
| Optional chaining | 좌결합성 | ?. |
|
| 19 | {{jsxref("Operators/new","new")}} (매개변수 리스트 생략) | 우결합성 | new … |
| 18 | {{jsxref("Operators/Arithmetic_Operators","후위 증가","#Increment", 1)}} | 없음 | … ++ |
| {{jsxref("Operators/Arithmetic_Operators","후위 감소","#Decrement", 1)}} | … -- |
||
| 17 | 논리 NOT | 우결합성 | ! … |
| 비트 NOT | ~ … |
||
| 단항 양부호 | + … |
||
| 단항 부정 | - … |
||
| 전위 증가 | ++ … |
||
| 전위 감소 | -- … |
||
| {{jsxref("Operators/typeof", "typeof")}} | typeof … |
||
| {{jsxref("Operators/void", "void")}} | void … |
||
| {{jsxref("Operators/delete", "delete")}} | delete … |
||
| {{jsxref("Operators/await", "await")}} | await … |
||
| 16 | 거듭제곱 | 우결합성 | … ** … |
| 15 | 곱셈 | 좌결합성 | … * … |
| 나눗셈 | … / … |
||
| 나머지 | … % … |
||
| 14 | 덧셈 | 좌결합성 | … + … |
| 뺄셈 | … - … |
||
| 13 | 비트 왼쪽 시프트 | 좌결합성 | … << … |
| 비트 오른쪽 시프트 | … >> … |
||
| 비트 부호 없는 오른쪽 시프트 | … >>> … |
||
| 12 | 미만 | 좌결합성 | … < … |
| 이하 | … <= … |
||
| 초과 | … > … |
||
| 이상 | … >= … |
||
| {{jsxref("Operators/in", "in")}} | … in … |
||
| {{jsxref("Operators/instanceof", "instanceof")}} | … instanceof … |
||
| 11 | 동등 | 좌결합성 | … == … |
| 부등 | … != … |
||
| 일치 | … === … |
||
| 불일치 | … !== … |
||
| 10 | 비트 AND | 좌결합성 | … & … |
| 9 | 비트 XOR | 좌결합성 | … ^ … |
| 8 | 비트 OR | 좌결합성 | … | … |
| 7 | 널 병합 연산자 | 좌결합성 | … ?? … |
| 6 | 논리 AND | 좌결합성 | … && … |
| 5 | 논리 OR | 좌결합성 | … || … |
| 4 | 조건 | 우결합성 | … ? … : … |
| 3 | 할당 | 우결합성 | … = … |
… += … |
|||
… -= … |
|||
… **= … |
|||
… *= … |
|||
… /= … |
|||
… %= … |
|||
… <<= … |
|||
… >>= … |
|||
… >>>= … |
|||
… &= … |
|||
… ^= … |
|||
… |= … |
|||
| 2 | {{jsxref("Operators/yield", "yield")}} | 우결합성 | yield … |
| {{jsxref("Operators/yield*", "yield*")}} | yield* … |
||
| 1 | 쉼표 / 시퀀스 | 좌결합성 | … , … |