[JavaScript] 연산

Rae-eun Yang·2022년 7월 25일
0

연산


연산자는 하나 이상의 표현식을 대상으로
산술, 할당, 비교, 논리, 타입, 지수 연산 등을 수행해
하나의 값을 만든다.
이때의 연산 대상을 피연산자(operand)라고 한다.

피연산자는 값으로 평가될 수 있는 표현식이어야 한다.
그리고 피연산자와 연산자로 이루어진 연산자 표현식도 값으로 평가될 수 있는 표현식이다.


연산자 종류


// 1. 산술 연산자
5 * 4 // -> 20
// 2. 문자열 연결 연산자
'My name is' + 'Yang' // -> 'My name is Yang'
// 3. 할당 연산자
color = 'red'	// -> 'red'
// 4. 비교 연산자
3 > 5 			// -> false
// 5. 논리 연산자
true && false 	// -> false
// 6. 타입 연산자
typeof 'Hi' 	// -> string
typeof 3		// -> number


1. 산술 연산자

5 + 3	// -> 8
5 - 3	// -> 1
5 * 3	// -> 15
5 / 3	// -> 1
5 % 3	// -> 1

단항 산술 연산자

// 단항 산술 연산자
1++		// -> 2
5--		// -> 4
var x = 5, result;

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

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

// 선할당 후감소(postfix decrement operator)
result = x--;
console.log(result, x); // 7 6

// 선감소 후할당(prefix decrement operator)
result = --x;
console.log(result, x); // 6 5

문자열 -> 숫자

var x = '1';

// 문자열 -> 숫자
console.log(+x);		// 1
// 부수 효과 X
console.log(x);			// "1"

// 불리언 -> 숫자
x = true;
console.log(+x)			// 1
// 부수 효과 X
console.log(x)			// true

// 불리언 -> 숫자
x = false;
console.log(+x)			// 0
// 부수 효과 X
console.log(x)			// false

// 문자열 -> 숫자 불가능할땐 NaN 반환
// 문자열이 숫자로 구성되어 있을때만 변경 가능
x = 'Hello';
console.log(+x);		// NaN
console.log(x);			// "Hello"

앞에 +를 붙여 숫자로 변환시키는 것은 자주 사용한다.



2. 문자열 연결 연산자

// 문자열 연결 연산자
'1' + 2;			// '12'
1 + '2';			// '12'
123 + '';			// '123'

타입 변환

// true는 1로 타입 변환됨
1 + true;			// 2

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

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

// undefined는 숫자로 타입 변환 불가능
+undefined;			// NaN
1 + undefined;		// NaN


3. 할당 연산자

  • 표현식인 문 : 값으로 평가될 수 있는 문
var x;

// 할당문은 표현식인 문
console.log(x = 10);		// 10


4. 비교 연산자

동등 비교 연산자

// 동등 비교
5 == 5;			// true

// 타입은 다르지만 압묵적 타입 변환을 통해 타입을 일치시키면 동등함
// 어느 것을 기준으로 타입을 일치시키는지는 js엔진에 따라..
5 == '5';		// true

일치 비교 연산자

// 일치 비교
1 === '1'		// false
0 === false		// false
// 주의할 점 : NaN는 자신과 같지 않은 유일한 값이다!
NaN === NaN				// false
Number.isNaN(NaN)		// true
Object.is(NaN, NaN)		// true

암묵적 타입 변환을 하지 않고 값을 비교하기 때문에 정확하다.
따라서 동등 비교 연산자보다 일치 비교 연산자를 쓰는 것을 권장한다.


isNaN()

isNaN(NaN)			// true
isNaN(undefined)	// true
isNaN(null)			// false
isNaN(-NaN)			// true / -NaN은 NaN와 같다
isNaN({})			// true

보다시피 isNaN()은 문제가 있다.
undefined, {}NaN으로 판단한다.


Number.isNaN()

Number.isNaN({})		// false
Number.isNaN(NaN)		// true
Number.isNaN(+'123sdf') // true

ES6에 나온 Number.isNaN()isNaN()보다 정확하다.
Number에서 숫자가 아닌 것을 걸러주기 때문!
Number.isNaN()을 사용하는 것을 권장한다.


Object.is()

0 === -0		// true
0 == -0			// true
Object.is(0, -0)		// false

아무튼 가장 정확한 비교는 늘 Object.is()를 사용하자!


대소 비교 연산자

// >, >=, <, <= 이런 것들..

삼항 연산자

var x = 2;

// 2 % 2 는 0이고 0은 false로 암묵적 타입 변환된다.
var result = x % 2 ? '홀수' : '짝수';

console.log(result);	// 짝수
var x = 10;

// if ...else 문은 표현식이 아닌 문이다.
// 따라서 값처럼 할당할 수 없다.
var result = if (x % 2) { result = '홀수'; } else { result = '짝수'; };
// SyntaxError : Unexpected token if


5. 논리 연산자

논리합 연산자

// 논리합 (||) 연산자
true || true;		// true
true || false; 		// true
false || true;		// true
false || false;		// false;

평가 진행 방향 : 좌항 -> 우항
논리합 연산자는 하나가 true이면 true를 리턴한다.
따라서 하나가 true라는 것을 확인하면 뒤에 것을 평가할 필요 없이 true를 리턴하게 된다.


논리곱 연산자

// 논리곱 (&&) 연산자
true && true;		// true
true && false;		// false
false && true;		// false
false && false;		// false

평가 진행 방향 : 좌항 -> 우항
논리곱 연산자는 앞이 true여야만 뒤에 것을 평가한다.
따라서 앞이 false라는 것을 확인하면 뒤에 것을 평가할 필요 없이 false를 리턴하게 된다.


논리 부정 연산자

// 논리 부정 (!) 연산자
!true;		// false
!false;		// true

// 형변환 활용
!(!true);	// true
!!1;		// true
!!'';		// false | 빈 문자열은 false의 값을 가진다.

단축 평가

// 단축 평가
'Cat' && 'Dog';		// 'Dog'

평가 진행 방향 : 좌항 -> 우항
첫 번째 피연산자 'Cat'은 Truthy 값이므로 true로 평가됩니다. 하지만 위 표현식은 이 시점에서 평가할 수 없습니다. 두 번째 피연산자까지 평가해 보아야합니다. 즉, 두 번째 피연산자가 논리곱 연산자 표현식의 평가 결과를 결정하며, 논리곱 연산자는 논리 연산의 결과를 결정하는 두 번째 피연산자 'Dog'를 그대로 반환합니다.


드모르간 법칙

// 드모르간 법칙
!(x || y) === (!x && !y)
!(x && y) === (!x || !y)

컴마 연산자

// 컴마 연산자
var x, y, z;

x = 1, y = 2, z = 3;	// 3
// 컴마 연산자는 앞 -> 뒤 로 실행되면서
// 마지막 오는 것을 값으로 평가한다.
function a() {
  var x, y;
  return x = 1, y = 2, console.log(x), console.log(y), console.log(x + y);
}

a()
// 1
// 2
// 3


6. 타입 연산자

typeof ''				// "string"
typeof 1				// "number"
typeof NaN				// "number"
typeof true				// "boolean"
typeof undefined		// "undefined"
typeof Symbol()			// "symbol"
typeof null				// "object"
typeof []				// "object"
typeof {}				// "object"
typeof new Date()		// "object"
typeof /test/gi			// "object"
typeof function () {}	// "function"

타입을 리턴해준다.



그 외 연산자

지수 연산자

Math.pow(2, 2);		// 4
2 ** 2;				// 4
Math.pow(3, 2);		// 9
3 ** 2;				// 9

// **= 도 가능하다
var x = 3
x **= 2				// 9

옵셔널 체이닝 연산자

// 다음과 같이 obj1, obj2 객체가 있다고 가정하자
const obj1 = {
  a : {
    b : {
      c : {
        d : 1
      }
    }
  }
}
  
const obj2 = {
  a : {
    b : 0
  }
}
// ?는 앞에 있는 것이 존재하지 않으면 undefined를 리턴한다
obj1.a?.b?.c?.d		// 1
obj2.a?.b?.c?.d		// undefined
// obj2.a.b.c는 값이 없는 것으로 판단이 됨
// 따라서 a에는 10이 할당되어진다
const a = obj2.a.b.c ?? 10;
a			// 10

// obj2.a.b 는 0의 값을 가지므로
// b에는 0이 할당되어진다
const b = obj2.a.b ?? 10;
b			// 0

delete, in, new, instanceof 연산자

// instanceof 연산자
[] instanceof Array		// true
//  in 연산자
// 객체에 특정 프로퍼티가 존재하는지
'a' in obj				// true
// delete 연산자
// 객체의 프로퍼티를 삭제하는 부수 효과가 있다
// 이는 o 객체를 사용하는 다른 코드에 영향을 준다
var o = { a : 1 };

delete o.a;
console.log(o);		// {}


연산자 우선순위

우선순위를 매기기 애매할때는 괄호로 묶어주자..
요즘은 prettier가 알아서 해준다!



연산자 평가 방향

할당 연산자는 우항 -> 좌항
그 외 연산자들은 모두 좌항 -> 우항 이라고 생각하면 편할듯!


profile
개발자 지망생의 벨로그

0개의 댓글