Truthy/Falsy 연산

  • if("" == 0) console.log("hello")는 출력이 될까 안될까? 된다. (빈문자열, 0은 둘다 false로 간주. 즉, 빈 문자열은 falsy한 값이다.)
let x;

console.log(1 < x); //false
console.log(x < 3); //false
if(1 < x < 3) console.log("hi") //hi

위의 코드에서는 x < 3 마저도 false가 출력되고, 1 < x < 3이 연산되는 기묘한 현상이 일어난다.

비교 연산자는 undefined랑 연산을 할때, NaN으로 간주되어 무조건 false를 반환한다.

그렇다면, null은 어떨까? null은 놀랍게도 0으로 간주된다.

이는 Javascript타입변환(Type Coercion) 규칙 중 하나이다. 이러한 암묵적 형변환 때문에 실제 개발에서는 가능한 명시적인 비교나 타입 체크를 하는 것이 권장되는 것이다.

1 < x < 3은 놀랍게도 참으로 간주된다. 이는 순차적으로 연산이 되기 때문이다. 1 < x 는 false를 반환, false는 0으로 간주되므로 false < 3은 true가 되어 hi가 출력되는 것이다.

Truthy값

Falsy값

0n은 BigInt의 자료형이다.


단락 회로 평가

OR 연산자

먼저 참이 오는 값을 반환한다.

true || true
false || true
true || false
false || (3 == 4)

위의 코드는 당연히 true, true, true, false 순으로 값이 반환될 것이다.

하지만, "Cat" || "Dog" -> Cat이 반환됨.

이는 OR연산자는 참값을 뱉어내는것이 아니라, 먼저 오는 참인 값을 반환하는 것이기 때문이다. 둘다 거짓인 경우에는, 뒤의 값이 반환된다.

"Cat" || "Dog" // "Cat"
"Cat" || false // "Cat"
false || "Cat" // "Cat"
"" || false // false
false || "" // ""
false || varObject // varObject

const result = null || 0 || undefined || "" || " " || 2 || "hello";
// result는 " "가 반환됨.

이를 활용한 간단한 예시

let input = prompt("값을 입력하세요")
let result = parseInt(input) || 10;
result += 2

입력값이 존재하지 않거나 숫자가 아니라면 기본값이 12가 된다.

AND 연산자

true && true
false && true
true && false
false && (3 == 4)

위의 코드는 당연히 true, false, false, false가 반환된다.

하지만, "Cat" && "Dog" -> Dog가 반환됨.

이는 AND 연산자는 먼저 오는 falsy인 값을 반환하기 때문에, 앞단이 true라면 뒤의 값도 검사해봐야하기 때문에 Dog가 반환된다.

false가 먼저 오고 true가 나중에 온다면, falsy의 값이 반환될 것이다.

false && "Cat"
"Cat" && false
"" && false
false && ""
false && varObject

const result = "a" && 3 && "undefined" && 0 && " " && 2;
// result는 0를 반환

이처럼, 단락회로 평가를 이용하면 불필요한 중첩 조건문을 간결하게 만들어줄 수 있다. 아래는 x의 형식이 string형식이며, 숫자형식의 문자열이고 30을 넘지 않는지 검사하는 코드이다.

//Before
if(typeof x = "string"){
	if(!isNaN(x)){
		if(parseInt(x) < 30){
			console.log("통과")
		}
	}
}

//After
let valid = typeof x === "string" && !isNaN(x) && parseInt(x) < 30;
연산자들 간의 우선순위도 존재한다. 예를들어, &&는   보다 우선적으로 처리됨.

const result = true || false && false true가 반환 const result = (true || false) && false false가 반환


기본값 설정하는 법

1. OR 연산자를 사용하는 방법

let name = null || "default string" //기본값으로 항상 default string을 반환

OR 연산자는 모든 falsy한 값에 대해 기본값을 적용하게 된다.

2. 널 병합 연산자를 사용하는 방법

좌항이 null/undefined일 경우, 우항을 반환하는 연산자. 이외의 경우는 좌항을 반환함.

let foo = null ?? "default string" //기본값으로 항상 default string을 반환
let baz = 0 ?? 42 // 0

널병합 연산자를 사용할때 유의할 점은, 오직 좌항이 null/undefined의 자료형일때만 우항을 반환하며, false나 기타 falsy값이어도 좌항을 반환한다.


숫자 산술 연산

3 + "3" // 33
3 * "3" // 9

3 + "a" // NaN
3 * "a" // NaN

NaN은 Not a Number의 약자

특정 값이NaN인지 Infinity인지 확인하는 방법은 한가지 밖에 없다. isNaN(), isFinite() 함수를 통해 비교 확인 가능


전개연산자

전개연산자는 배열이나 객체를 펼치는 연산자이다. 배열/객체 내의 요소들을 펼치는 역할을 한다.

const array = [1, 2, 3, 4, 5];
const result = [...array];
console.log(result) //[1, 2, 3, 4, 5]

전개연산자는 어디에 쓰이냐에 따라 다른 역할을 한다.

  • 배열 복사

얕은 복사를 할때 사용한다. (참조타입까지는 연결이 끊어지지 않는다.)

//원시 타입은 연결이 끊어진다.
const original = [1, 2, 3];
const copy = [...original];

// 배열 자체는 별개의 인스턴스
console.log(original === copy); // false

// 최상위 요소 변경은 서로 영향 없음
copy[0] = 100;
console.log(original[0]); // 1 (변경되지 않음)
console.log(copy[0]); // 100

//but, 참조타입은 연결이 끊어지지 않는다.
const original = [1, {name: 'John'}, [3, 4]];
const copy = [...original];

// 참조 타입 요소 변경은 서로 영향을 미침
copy[1].name = 'Jane';
copy[2][0] = 99;

console.log(original[1].name); // 'Jane' (변경됨)
console.log(original[2][0]); // 99 (변경됨)

깊은 복사에 대한 내용은 여기에서 더 자세히 확인해볼 수 있다.

  • 배열 결합
const array1 = [1, 2, 3];
const array2 = [4, 5, 6];
const result = [...array1, ...array2];
console.log(result) //[1, 2, 3, 4, 5, 6]
  • 객체 복사
const obj = {a: 1, b: 2, c: 3};
const result = {...obj};
console.log(result) //{a: 1, b: 2, c: 3}
  • 객체 결합
const obj1 = {a: 1, b: 2};
const obj2 = {c: 3, d: 4};
const result = {...obj1, ...obj2};
console.log(result) //{a: 1, b: 2, c: 3, d: 4}

‼️ 모든 글이 정확하지 않을 수 있습니다. 잘못된 정보가 있을 경우 댓글로 알려주시면 감사하겠습니다.