관리 메뉴

흰둥씨의 개발장

[자바스크립트] 딥다이브) 연산자 본문

BoOk/JS deep dive

[자바스크립트] 딥다이브) 연산자

돈워리비해삐 2023. 4. 21. 05:26

연산자 : 하나의 표현식을 대상으로 산술, 할당, 비교, 논리, 타입, 지수연산 등을 수행해 값을 만든다

피연산자 : 연산의 대상 =>값으로 평가될 수 있는 표현식이어야 함 

 

연산자 표현식도 값으로 평가될 수 있는 표현식이어야 한다. 

 

1) 산술 연산자 

ㄴ피연산자 대상으로 수학적계산 수행

ㄴ산술 연산 불가능한 경우 NaN반환

 

  - 1) 이항 산술 연산자 

ㄴ 덧셈(+), 뺄셈(-), 곱셈(*), 나눗셈(/), 나머지(%) 

ㄴ부수 효과(side effect) 없음(피 연산자의 값이 바뀌는 경우는 없고, 언제나 새로운 값을 만듦)

 

  - 2) 단항 산술 연산자

ㄴ증가 (++), 감소(--), 음수를양수로 반전하지 않음(+), 양수를 음수로, 음수를 양수로 값 반전함(-)

ㄴ증가, 감소는 부수 효과 있다. 

let x = 1;
x++; // 증가는 값을 변경하는 암묵적 할당이 이루어짐 
console.log(x); // 2
x--; // 감소도 값을 변경하는 암묵적 할당이 이루어짐 
console.log(x); //1

'전위 증가/ 감소' : 먼저 피연산자의 값을 증가/ 감소 시킨후 다른 연산을 수행

'후위 증가/ 감소' : 먼저 다른 연산 수행후 피연산자의 값을 증가 / 감소시킴

let x = 5, result;
result = x++;
console.log(result, x) // 5, 6 선할당, 후증가

result = ++x;
console.log(result, x) // 7, 7 선증가, 후할당

result = x--;
console.log(result, x) // 7, 6 선할당, 후증가

result = --x;
console.log(result, x) // 5, 5 선증가, 후할당
let x = '1';
console.log(+x); //1 문자열에서 숫자로 타입변환함
console.log(x);  //"1" 부수효과없음 => 본래 값이 바뀌지 않음 

x = true;
console.log(x); //true
console.log(+x); //1 boolean값을 숫자로 타입변환함

x = false;
console.log(x); // false
console.log(+x);  //0 boolean값을 숫자로 타입변환함

x = 'Hello';
console.log(x); //'Hello'
console.log(+x);  //NaN

+10 //10
+(-10);  //-10

-(-10) //10
-'10'  //-10 문자열을 숫자로 타입변환
-true;  //-1 boolean을 숫자로 타입변환
-'Hello';  //NaN 문자열은 숫자로 타입변환 할수 없어서 NaN

 

 

  - 3) 문자열 연결 연산자

ㄴ+연산자는 피연산자 중 하나이상이 문자열 인경우 문자열 연결 연산자로 동작함

ㄴ그 외에는 산술연산자로 동작

'1' + 2 ; // '12' 
1 + '2' ; //'12' 

1 + 2 ; //3

1 + true ;  //2 true는 1으로 타입변환 
1 + false ; // 1 false는 0으로 타입변환

1 + null ; //1 null은 0으로 타입변환

+undefined;  //NaN
1 + undefined; //NaN 
//undefined는 숫자로 타입변환 되지 않음

위 예제와 같이 개발자의 의도와 상관없이 자바스크립트 엔진에 의해 암묵적으로 타입변환이 자동으로 일어남 

ㄴ암묵적 타입변환(implicit coercion) = 타입 강제 변환(type coercion)

 

 

2) 할당연산자(assignment operator)

ㄴ우항에 있는 피연산자의 평가 결과를 좌항에 있는 변수에 할당

ㄴ= , +=, -=, *=, /=, %= 

ㄴ모두 부수효과 있음 

let str = 'Hello';
str += 'world';
console.log(str) // 'Hello world'

 

 

3) 비교 연산자 (Comparison operator)

ㄴ좌항과 우항의 피연산자 비교한후 결과를 boolean으로 반환

ㄴif문이나 for과 같은 제어문에서 조건식으로 주로 사용

 

  - 1) 동등 / 일치 비교 연산자

== 동등비교(값이 같음), === 일치비교(타입까지 같음), != 부동등비교(값이 다름), !== 불일치 비교 (타입까지 다름)

5 == '5' //true
5 === '5' //false

'0' == '' //false
0 == ''  //true

false == 'false' //false
false == '0' //true

false == null //false
false == undefined  //false

=== 일치 연산자는 값도 타입도 같아야만 true를 반환한다

그러나 일치연산자도 NaN과 숫자 0을 거를 수 없다. (자바스크립트에는 양의 0과 음의 0이 있는데 이를 비교하면 true를 반환함)

NaN === NaN //false ; NaN이 자신과 일치 하지 않는 유일한 값임

//Number.isNaN은 NaN인지 확인하고 NaN이면 true를 반환함 
Number.isNaN(NaN);  //true
Number.isNaN(10);  //false
Number.isNaN(1+undefined);  //true

0 === -0//true
0 == -0 //true
Object.is(value1, value2);

Object.is(+0, -0);  //false
Object.is(NaN, NaN);  //true

Object.is메서드는 +0과 -0을 구별함 (boolean반환)

 

 

  - 2) 대소 관계 비교 연산자

ㄴ> 크다, <작다, >= 크거나 같다, <= 작거나 같다

ㄴ부수효과없음

 

 

4) 삼항 조건 연산자

조건식 ? true일때 반환값 : false일때 반환값

let x = 2;
let result1 = x % 2 ? '홀수' : '짝수';  //0은 false로 암묵적 타입변환
console.log(result1); //짝수

let result2 = if( x % 2 ){ return = '홀수'; } else{ return = '짝수';} //Error
//if...else문은 표현식이 아닌 문으로 값처럼 사용불가
//삼항 조건 연산자 표현식은 표현식인 문이다. 따라서 값처럼 사용가능

 

 

5) 논리 연산자

ㄴ || OR연산자, && AND연산자 , ! NOT연산자

ㄴ부수효과 없음

true || true; //true
true || false; //true
false || true; //true
false || false; //false

true && true; //true
true && false; //false
false && true; //false
false && false;  //false

!true; //false
!false; //true
!0;  //true
!'hello'  //false

ㄴ위 를 토대로 '단축평가' 가능 

'고양이' && '강아지' // '강아지'
'고양이' || '강아지' // '고양이'

 

**드모르간의 법칙

!(x || y) == (!x && !y)
!(x && y) == (!x || !y)

 

6) 쉼표 연산자 

ㄴ왼쪽 피연산자 부터 차례대로 피연산자 평가하고 마지막 피연산자의 평가가 끝나면 마지막 피연산자의 평가결과를 반환

let x, y, z;
x = 1, y = 2, z = 3; //3

 

 

7) 그룹 연산자 

ㄴ소괄호로 피연산자를 감싼것 

ㄴ연산자 우선순위가 가장 높다

10 * 2 + 3 //23 사칙연산법칙그대로 적용되어서 *곱셈먼저 이후 +덧셈함 
10 * (2 + 3) //50 그룹연산자로 +먼저 됨

 

 

8) typeof 연산자 

ㄴ피연산자의 데이터 타입을 문자열로 반환

ㄴ'string', 'number', 'boolean', 'undefined', 'symbol', 'object', 'function' 중하나 반환 ('null'반환 하는 경우 없음 )

typeof null // object
typeof []   // object
typeof {}   // object
typeof new Date()  // object
typeof /test/g    // object

null타입인지 확인할때는 ===일치 연산자 사용할 것

선언하지 않은 식별자를 typeof로 연산시 undefined반환함 

let x = null;
typeof x === null; // false
x === null;        //true

typeof y ; //undefined  <= 선언한적 없는 y를 type체크했을 때 error가 안뜬다

 

9) 지수 연산자 

ㄴ이항 연산자 중 가장 우선순위 높음 

2 ** 2 ; // 4 ; 2의 2제곱
2 ** 0 ; //1  ;2의 0제곱
2 ** -2; //0.25

Math.pow(2, 2) //4;  2의 2제곱
(-5) ** 2 //25 ;음수의 제곱은 ()사용해야함

let x = 5
x **= 2; // 25 할당 연산자와 사용가능

2 * 5 ** 2 //50 ; 5의 2제곱먼저 연산후 2와 곱해짐

 

 

10) 그외 연산자 

?.   옵셔널 체이닝 연산자
??  null 병합 연산자 
delte 프로퍼티 삭제
new 생성자 함수 호출시 사용해서 인스턴스 생성
instanceof  좌변의 객체가 우변의 생성자 함수와 연결된 인스턴스인지 판별
in 프로퍼티 존재 확인

 

 

11) 부수효과 있는 연산자

ㄴ할당연산자 (=), 증감연산자(++/--), delete연산자 

let x;
x = 1; //x값이 1로 변경됨, x를 사용하는 다른 코드에 영향줌 
x++ ; // x값이 2로 변경됨, x를 사용하는 다른 코드에 영향줌 

let obj = {a : 1};
delete obj.a; // 객체 프로퍼티 삭제해서 obj를 사용하는 다른 코드에 영향줌 
console.log(obj) // {}

 

 

12) 연산자 우선순위

ㄴ여러개의 연산자로 이루어진 문이 실행될때 연산자가 실행되는 순서

우선순위 연산자
1 ()
2 new(매개변수 존재) , . , []프로퍼티접근, ()함수호출, ?. 옵셔널체이닝연산자
3 new(매개변수 미존재)
4 x++, x--
5 !x, +x, -x, ++x, --x, typeof, delete
6 ** 제곱(이항연산자중에서 우선순위제일높음)
7 *, /, %
8 +, -
9 <, <=, >, >=, in, instanceof
10 ==, !=, ===, !==
11 ??
12 &&
13 ||
14 ? ... : ... (삼항)
15 할당연산자(=, +=, -=, ...)
16

 

 

13) 연산자 결합순서

좌항 => 우항 + - / % < <= > >= && || . [] () ?? ?. in instanceof
우항 => 좌항 ++ -- 할당연산자(=,+=,-=,...) !x +x -x ++x --x typeof delete ? ... : ... **