본문 바로가기
Programming/자바스크립트

[자바스크립트] SCE & Nullish 병합

by 코딩하는 랄로 2023. 10. 25.
반응형

SCE란

SCE란 Short Circuit Evalution의 줄일말로 최단거리 연산을 뜻한다. 최단거리 연산은 연산식에 대한 연산 중 결과가 나온 시점에서는 남은 연산을 처리하지 않는 것이다. 필요한 까지만 연산을 처리하기 때문에 lazy(게으른) evalutation라고도 한다.

 

SCE 연산은 &&(AND), ||(OR) 연산에 적용이 된다. 먼저 아래의 예제를 살펴보자.

// SCE
// && : AND
let result;

result = true && false;
console.log(result); //false

result = true && 'hello';
console.log(result); //hello

result = 0 && 'hello';
console.log(result); //0


// || : OR
result = 'hello' || 'bye';
console.log(result); //hello

result = 0 || 200;
console.log(result); //200

result = null || 'good'
console.log(result); //good

위의 예제가 왜 저런 결과를 나타내는지 살펴보기 위해 논리연산자 &&, || 에 대해서 자세히 살펴보자.

 

 

&& 연산

논리 연산자의 AND(&&)는 다음의 연산 결과들을 가진다.

연산식 결과
true && true true
true && false false
false && true false
false && false false

 

위의 표를 보면 AND 연산자가 다음과 같은 규칙을 가지는 것을 볼 수 있다.

  • 첫번째 피연산자가 true이면, 두번째 피연산자에 의해 결과가 정해진다.
  • 첫번째 피연산자가 false이면, 두번째 연산자에 관계없이 false이다.

즉, &&연산에서 SCE 연산은 첫번째 피연산자가 true이면 두번째 피연산자에 의해 무조건 결정되기 때문에 두번째 피연산자를 연산의 결과로 가지고, 첫번째 피연산자가 false이면, 첫번째 피연산자를 연산의 결과로 가지는 것이다.

//첫번째 피연산자 : true
//result <= 두번째 피연산자
result = true && false;
console.log(result); //false

//첫번째 피연산자 : true
//result <= 두번째 피연산자
result = true && 'hello';
console.log(result); //hello

//첫번째 피연산자 : false : 0 is falsy value
//result <= 첫번째 피연산자
result = 0 && 'hello';
console.log(result); //0

 

 

|| 연산

논리 연산자의 OR(||)는 다음의 연산 결과들을 가진다.

연산식 결과
true || true true
true || false true
false || true true
false || false false

 

위의 표를 보면 OR 연산자가 다음과 같은 규칙을 가지는 것을 볼 수 있다.

  • 첫번째 피연산자가 true이면, 두번째 연산자에 관계없이 true이다.
  • 첫번째 피연산자가 false이면, 두번째 피연산자에 의해 결과가 정해진다.

즉, ||연산에서 SCE 연산은 첫번째 피연산자가 true이면 첫번째 피연산자를 연산의 결과로 가지고 첫번째 피연산자가 false이면, 두번째 피연산자를 연산의 결과로 가지는 것이다.

//첫번째 피연산자 : true
//result <= 첫번째 피연산자
result = 'hello' || 'bye';
console.log(result); //hello

//첫번째 피연산자 : false => ''(empty string) is falsy value
//result <= 두번째 피연산자
result = '' || 200;
console.log(result); //200

//첫번째 피연산자 : false => null is falsy value
//result <= 두번째 피연산자
result = null || 'good'
console.log(result); //good

 

 

다중 연산

연산자가 다음과 같이 여러개가 있을 때는 어떠한 결과를 리턴할까?

// 다중 연산
let result;
result = true && 1 && 'hi' && 0;
console.log(result); //0

result = true && 1 && 0 && 'hi';
console.log(result); //0

result = true && null && 0 && 'hi';
console.log(result); //null

result = 0 || undefined || '' || 1;
console.log(result); //1

result = null || 1 || 'hi' || 0;
console.log(result); //1

result = false || null || 1 || 0;
console.log(result); //1

위의 예제를 통해 다음과 같은 규칙을 발견할 수 있게 된다.

  • && 연산 => 처음 만나는 false 값을 나타내는 표현식을 반환, 없을 경우 마지막 표현식을 반환
  • || 연산 => 처음 만나는 true값을 나타내는 표현식을 반환, 없을 경우 마지막 표현식을 반환

 

 

SCE 사용 이유

SCE를 사용하면 특정 변수가 유효할 때만 동작을 하는 코드를 작성해야 하는 경우나, 특정 변수에 유효하지 않은 값이 들어올 때의 동작 코드 등을 간결하게 작성할 수 있다.

 

예를 들어, 두 숫자를 넘겨받아 더해서 넘겨주는 함수를 선언한다고 해보자.

function addNum(num1, num2) {
    return num1 + num2;
};


console.log(addNum(1, 3)); //4
console.log(addNum(1)); //NaN
console.log(addNum()); //NaN

 

이 때, 함수의 인수를 넘겨 주지 않을 경우, NaN 값을 출력하지 않게 하기 위해서는 다음과 같이 코드를 작성할 수 있다.

function addNum(num1, num2) {
    num1 = num1 || 0;
    num2 = num2 || 0;
    return num1 + num2;
};


console.log(addNum(1, 3)); //4
console.log(addNum(1)); //1
console.log(addNum()); //0

 

또는 특정 배열에 주어진 값이 홀수 일때에만 배열에 추가하고 싶을 때에는 다음과 같이 코드를 작성할 수 있다.

const arr = []
for(let i = 1; i <= 10; i++) {
    (i % 2) && arr.push(i);
}

console.log(arr); //[1, 3, 5, 7, 9]

 

SCE를 잘 활용한다면, 값의 유효성에 따른 동작 뿐만이 아니라 조건에 따른 동작에서도 간결하고 실행 cost도 줄일 수 있는 코드를 작성할 수 있다.

 

 

Nullish 병합

nullish 병합은 ES2020에서 등장한 연산자로 ??를 사용한다. nullish 연산자는 SCE 연산의 범위를 더욱 더 줄인 연산이다. SCE 연산에서는 false값을 자바스크립트의 모든 falsy값을 취급하지만, nullish 병합 연산에서는 null과 undefined값만을 false값으로 처리한다.

 

이 때에 ?? 연산은 SCE연산에서 || 연산과 똑같이 동작한다. null, undefined일 때 false이고, 그렇기 때문에 뒤의 피연산자에 의해 값이 결정된다.

// nullish
// null, undefined만 false로 처리
let result;

result = null ?? 10;
console.log(result); //10

result = '' ?? 10;
console.log(result); //''

result = undefined ?? 10;
console.log(result); //10

result = 0 ?? 10;
console.log(result); //0
반응형