새로운 경험

[TIL] 2022-11-11 Operators 연산자 JavaScript

시바카오 2022. 11. 11.

산술 연산자(Arithmetic operators)

 

// 산술 연산자 (Arithmetic operators)
// + 더하기
// - 빼기
// * 곱하기
// / 나누기
// % 나머지값
// ** 지수 (거듭제곱)

console.log(5 + 2);
console.log(5 - 2);
console.log(5 * 2);
console.log(5 / 2);
console.log(5 % 2);
console.log(5 ** 2); // es7에 추가된 거듭제곱
console.log(Math.pow(5, 2)); // 과거에는 거듭제곱을 이렇게 사용했음

// + (플러스) 연산자 사용시에 주의점!
let text = '두개의' + '문자를';
console.log(text);
text = '1' + 1; // 숫자와 문자열을 더하면 문자열로 변환됨
console.log(text);

 

 

단항 연산자 (Unary operators)

// 단항 연산자 Unary Operators
// + (양)
// - (음)
// ! (부정)
let a = 5;
a = -a; // -1 * 5
console.log(a);
a = -a;
console.log(-a);

a = +a;
console.log(a);
a = -a; // -5
a = +a; // +(-5)
console.log(a);

let boolean = true;
console.log(boolean);
console.log(!boolean);
console.log(!!boolean);

// + 연산자를 쓸 때 
// 숫자가 아닌 타입들을 숫자로 변환하면 어떤 값이 나오는지 확인할 수 있음.
console.clear();
console.log(+false); // 0 
console.log(+null); // 0
console.log(+''); // 0
console.log(+true); // 1
console.log(+'text'); // NaN
console.log(+undefined); // NaN

console.log(!!1); // !부정연산자 - 한 번만 부정하면 반대의 boolean값
// !! 부정의 부정을 하면 값을 boolean 타입으로 변환함.

 

 

할당 연산자 (Assignment operators)

축약버전을 잘 알아두자

// 할당 연산자 (Assignment operators)

let a = 1;
a = a + 2;
console.log(a);

a += 2; // a = a + 2; 축약버전.
console.log(a); //5

a -= 2; // a = a - 2; , 5 - 2 = 3
console.log(a);

a *= 2; // a = a * 2; , 3 * 2 = 6
console.log(a);

a /= 2;
console.log(a); // a = a / 2; , 6 / 2 = 3

a %= 2; // a = a / 2 의 나머지값 , 3 / 2 의 나머지값은 1
console.log(a);
a **= 2; // a = a^2 , 1의 제곱은 1
console.log(a);

 

 

 

증가 & 감소 연산자 (Increment & Decrement operators)

 

// a++ 필요한 연산을 하고, 그 뒤 값을 증가시킴
// ++a 값을 먼저 증가하고, 필요한 연산을 함

// 증가 & 감소 연산자 (Increment & Decrement operators)
let a = 0;
console.log(a);
a++; // a = a + 1;
console.log(a);
a--; // a = a - 1;
console.log(a);

console.clear();
// 주의!
// a++ 필요한 연산을 하고, 그 뒤 값을 증가시킴
// ++a 값을 먼저 증가하고, 필요한 연산을 함

a = 0;
console.log(a++);
console.log(a);
let b = a++;
console.log(b);
console.log(a);

 

비교 연산자 (Relational operators)

// 등호를 이용하여 특정한 값과 값을 비교할때 사용

// 대소 관계 비교 연산자 (Relational operators)
// 특정한 값과 값을 비교할 때 사용
// > 크다
// < 작다
// >= 크거나 같다
// <= 작거나 간다
console.log(2 > 3);
console.log(2 < 3);
console.log(3 < 2);
console.log(3 > 2);
console.log(3 <= 2);
console.log(3 <= 3);
console.log(3 >= 3);
console.log(3 >= 2);

 

연산자 우선순위 (Priority of operators)

MDN 연산자 우선순위 : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence

(언어 한국어로 변환 가능.)

 

Operator precedence - JavaScript | MDN

Operator precedence determines how operators are parsed concerning each other. Operators with higher precedence become the operands of operators with lower precedence.

developer.mozilla.org

연습

Tip ! 연산자 우선순위를 조절하고자 한다면 소괄호()로 우선 연산하고자 하는 것들을 묶어줌.

더보기

우선순위와 결합성

아래와 같이 표현할 수 있는 표현식을 생각해 봅시다. 연산자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을 출력, 괄호로 인해 실행 순서가 바뀜
Copy to Clipboard

좌결합성(왼쪽에서 오른쪽으로)은 표현식이 (a 연산자1 b) 연산자2 c와 같이, 우결합성(오른쪽에서 왼쪽으로)은 a 연산자1 (b 연산자2 c)와 같이 계산된다는 의미입니다. 대입 연산자는 우결합성이므로 다음과 같은 코드를 작성할 수 있습니다.

a = b = 5; // a = (b = 5);와 같음
Copy to Clipboard

이때 대입 연산자는 대입된 값을 반환하므로 a와 b의 값이 5가 됨을 예상할 수 있습니다. 우선 b의 값이 5로 설정되고, 그 다음에는 a의 값이 우변인 b = 5의 반환값 5로 설정됩니다.

다른 예시로, 좌결합성인 다른 산술 연산자와 달리 거듭제곱 연산자 (**)만은 우결합성입니다. 흥미로운 점으로 표현식의 평가는 결합성과 무관하게 항상 왼쪽에서 오른쪽으로 진행됩니다.

코드 출력
Copy to Clipboard
 
Copy to Clipboard
 

여러 연산자의 우선순위가 같을 때는 결합성을 고려합니다. 위에서와 같이 연산자가 하나이거나 연산자끼리 우선순위가 다를 경우에는 결합성이 결과에 영향을 미치지 않습니다. 아래의 예제에서 같은 종류의 연산자를 여러 번 사용했을 때 결합성이 결과에 영향을 미치는 것을 확인할 수 있습니다.

코드 출력
Copy to Clipboard
 
Copy to Clipboard
 
Copy to Clipboard
 

위의 예제에서 나눗셈은 좌결합성이므로 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과 같다.
Copy to Clipboard

그룹화와 단락에 대한 참고사항

아래 표에서 그룹화는 우선 순위가 가장 높은 것으로 나열됩니다. 그러나 이것이 항상 그룹화 기호( … ) 내의 표현식이, 특히 단락과 관련하여 먼저 평가된다는 것을 의미하지는 않습니다.

단락은 조건부 평가의 전문 용어입니다. 예를 들어 표현식 a &&(b + c)에서 a가 falsy이면 하위 표현식(b + c)은 괄호 안에 있어도 평가되지 않습니다. 논리 분리 연산자("OR")가 "단락"되었다고 말할 수 있습니다. 논리적 분리와 함께 다른 단락 연산자에는 논리적 연결("AND"), nullish-coalescing, 선택적 연결 및 조건부 연산자가 포함됩니다. 몇 가지 예가 더 있습니다.

a || (b * c);  // `a`를 먼저 평가하고, `a`가 "truthy"라면  `a`를 생성합니다.
a && (b < c);  // `a`를 먼저 평가하고, `a`가 "falsy"라면  `a`를 생성합니다.
a ?? (b || c); // `a`를 먼저 평가하고, `a`가 `null`과 `undefined`가 아니라면 `a`를 생성합니다. 
a?.b.c;        // `a`를 먼저 평가하고, `a`가 `null`또는 `undefined`라면 `undefined`를 생성합니다.
Copy to Clipboard

다음 표는 우선순위 내림차순(19부터 1까지)으로 정렬되어 있습니다.

우선순위연산자 유형결합성연산자
19 그룹 없음 ( … )
18 멤버 접근 좌결합성 … . …
계산된 멤버 접근 좌결합성 … [ … ]
new (인자 리스트 제공) 없음 new … ( … )
함수 호출 좌결합성 … (  )
옵셔널 체이닝 좌결합성 ?.
17 new (인자 리스트 생략) 우결합성 new …
16 후위 증가 (en-US) 없음 … ++
후위 감소 (en-US) … --
15 논리 NOT (en-US) 우결합성 ! …
비트 NOT (en-US) ~ …
단항 양부호 + …
단항 부정 - …
전위 증가 (en-US) ++ …
전위 감소 (en-US) -- …
typeof typeof …
void void …
delete delete …
await await …
14 거듭제곱 우결합성 … ** …
13 곱하기 좌결합성 … * …
나누기 … / …
나머지 … % …
12 더하기 좌결합성 … + …
빼기 … - …
11 비트 왼쪽 시프트 (en-US) 좌결합성 … << …
비트 오른쪽 시프트 (en-US) … >> …
비트 부호 없는 오른쪽 시프트 (en-US) … >>> …
10 미만 (en-US) 좌결합성 … < …
이하 (en-US) … <= …
초과 (en-US) … > …
이상 (en-US) … >= …
in … in …
instanceof … instanceof …
9 동등 좌결합성 … == …
부등 … != …
일치 (en-US) … === …
불일치 (en-US) … !== …
7 비트 AND 좌결합성 … & …
7 비트 XOR (en-US) 좌결합성 … ^ …
6 비트 OR (en-US) 좌결합성 … | …
5 논리 AND (en-US) 좌결합성 … && …
4 논리 OR (en-US) 좌결합성 … || …
널 병합 연산자 좌결합성 … ?? …
3 조건 (삼항) 우결합성 … ? … : …
2 할당 (en-US) 우결합성 … = …
… += …
… -= …
… **= …
… *= …
… /= …
… %= …
… <<= …
… >>= …
… >>>= …
… &= …
… ^= …
… |= …
… &&= …
… ||= …
… ??= …
yield 우결합성 yield …
yield* yield* …
1 쉼표 / 시퀀스 좌결합성 … , …

 

동등 비교 연산자 (Equality operators)

// 동등 비교 관계 연산자 (Equality operators)
// == 값이 같음
// != 값이 다름
// === 값과 타입이 둘 다 같음 //✨ 코딩을 할 때는 타입비교 연산자를 주로 사용하는 것이 Good !
// !== 값과 타입이 다름
console.log(2 == 2);
console.log(2 != 2);
console.log(2 != 3);
console.log(2 == 3);
console.log(2 == '2'); // True ! 타입은 다르지만 문자'2'가 숫자로 자동변환 되기 때문.
console.log(2 === '2'); // False ! 타입이 엄연히 다르기 때문 !
console.log(true == 1); // 1을 boolean으로 변환하면 True이기 때문 !
console.log(true === 1);
console.log(false == 0); // 0을 boolean으로 변환하면 False이기 때문 !
console.log(false === 0);

console.clear();

const obj1 = {
    name : 'js',
}; // 0x0001
const obj2 = {
    name : 'js',
}; // 0x0002

// 내용물(key와 value)자체는 'js'로 같긴 하지만, 
// obj1과 obj2에는 각각 다른 메모리 영역(주소)을 사용하기 때문.

console.log(obj1 == obj2);
console.log(obj1 === obj2); // type은 둘 다 object지만, 값 자체가 다르기 때문에 false !
console.log(obj1.name == obj2.name);
console.log(obj1.name === obj2.name); // 내용물끼리만 비교한것이기에 true !

let obj3 = obj2;
console.log(obj3 == obj2);
console.log(obj3 === obj2); // true ! obj3에 obj2의 메모리주소를 그대로 복붙하기 때문 !

Tip !

하나하나 다 짚고 넘어가려면 끝이 없음.

필요 할 때 한 번씩 다시 찾아보고, 처음엔 조금조금씩 러프하게 알아가는 것이 중요함 !

JavaScript 참고서 (https://developer.mozilla.org/ko/docs/Web/JavaScript)

댓글

💲 추천 글