본문 바로가기

[ONEBITE-REACT] JS 심화 - Truthy와 Falsy

codeConnection 2024. 3. 12.

의미

자바스크립트는 true나 false인 조건이 주어지지 않아도, true나 false로 인식하는 경우가 있다.

이런 경우를 Truthy(참 같은 값), Falsy(거짓 같은 값)라고 한다.

if (123) {
    console.log("true");
}  else {
    console.log("false");
} // true

if (undefined) {
    console.log("true");
} else {
    console.log("false");
} // false

위의 코드를 보면 '123이 124보다 크면' 이런 조건을 붙인 것이 아니라 그냥 123이라는 number type 자체를 조건식에 넣었고, 이것이 true면 "true" false면 "false"를 반환하도록 하였다.
그런데 true를 반환했고, 마찬가지로 아래에서는 undefined에 대해 참과 거짓을 묻자 false로 반환했다.

종류

truthy

  • true
  • number type (0 제외)
  • string (공백-빈 문자열 제외)
  • object
  • array
  • function

falsy

  • false
  • 0
  • -0
  • 빈 문자열 ("")
  • null
  • undefined
  • NaN (Not a Number-숫자가 아님)

활용

예를 들어 아래와 같이 person이라는 객체를 만들고, name : "장원영"이라는 프로퍼티를 넣어 관리하고 있다고 가정해보자.

function printName(person) {
    console.log(person.name)
}

let person = {
    name : "장원영",
}

printName(person); // "장원영"

코드해석

function을 사용하여 printName이라는 함수를 선언하고 파리미터로 person이라는 변수를 받도록 했다.
이 함수가 실행되면 console에 person이라는 객체 중 name 프로퍼티의 내용을 출력하도록 했다.

그리고 person이라는 객체를 선언한다. 이 객체의 프로퍼티는 name : "장원영"이다.

후에 이 함수를 실행시키면 2번줄이 실행되어 console에 person 객체의 name 프로퍼티가 출력된다.

그런데 만약, 위처럼 person 객체가 정확하게 할당되어 있는 것이 아니라 오류나 실수 또는 의도에 의해 프로퍼티가 없는 빈 객체일 경우에는 에러가 출력된다.

function printName(person) {
    console.log(person.name)
}

let person;

printName(person); // Uncaught TypeError: Cannot read properties of undefined (reading 'name')

위 TypeError는 person 객체의 값이 초기화 되어 있지 않은, 즉 undefined 상태인데 person 객체의 name 프로퍼티에 접근하고자 하니 출력하는 에러이다.
(에러 내용 : undefined 상태에서는 'name' 프로퍼티를 읽어올 수 없다.)

그래서 이런 경우에는 console.log가 실행되기 전에 if문을 추가해서 person 객체가 undefined인지 확인하고 맞다면 에러메시지를 출력하고 난 뒤 코드가 더 진행해서 에러를 발생시키지 못하도록 return 시킨다.

function printName(person) {
  if (person === undefined) {
    // person이 undefined인지 확인하고
    console.log("person의 값이 없습니다."); // 맞다면 에러 메시지를 출력하고
    return; // 밑으로 이어가지 못하게 return 시키기
  }
  console.log(person.name);
}

let person;

printName(person); // person의 값이 없습니다.

그런데 이 때 person 객체에 개발자가 의도적으로 초기값을 null로 할당하면 undefined 상태가 아니라 null 상태이기 때문에 또 에러가 발생한다.

function printName(person) {
  if (person === undefined) {
    // person이 undefined인지 확인하고
    console.log("person의 값이 없습니다."); // 맞다면 에러 메시지를 출력하고
    return; // 밑으로 이어가지 못하게 return 시키기
  }
  console.log(person.name);
}

let person = null;

printName(person); // Uncaught TypeError: Cannot read properties of null (reading 'name')

따라서 undefined와 마찬가지로 null을 확인하는 조건식도 하나 더 추가해주어야 한다.

function printName(person) {
  if (person === undefined || person === null) {
    // person이 undefined 또는 null인지 확인하고
    console.log("person의 값이 없습니다."); // 맞다면 에러 메시지를 출력하고
    return; // 밑으로 이어가지 못하게 return 시키기
  }
  console.log(person.name);
}

let person = null;

printName(person); // person의 값이 없습니다.

여기까지가 일반적인 상황이다. 그런데 지금은 객체나 조건문이 간단하고 함수가 하나여서 그렇지만 웹 사이트를 개발하면서 함수가 많아질수록 이렇게 조건문을 계속 추가하는 것은 코드를 복잡하게 만든다는 단점이 있다.

  if (person === undefined || person === null)

따라서 이럴 때 falsy 성질을 이용하면 간편하게 표현 가능하다.

undefined와 null은 둘 다 falsy이다. 그렇기 때문에 ! not 연산자를 사용하면, !person, 즉 person이 'false가 아니면'이라는 의미가 되고 false가 아니면 true를 말하는 것이다.
즉 true면 if문에서는 true일 때 실행하라는 코드를 실행하게 된다. 여기서는 console.log에 "person의 값이 없습니다"라는 텍스트를 출력하게 된다.

function printName(person) {
  if (!person) {
    console.log("person의 값이 없습니다.");
    return;
  }
  console.log(person.name);
}

let person = null;

printName(person); // person의 값이 없습니다.

다시 null을 빼고 name 프로퍼티를 추가해보면 정상 person이 falsy가 아닌 게 아니기 때문에 (false가 맞기 때문에)
if문을 실행하지 않고 다음으로 넘어가서 console에 person.name 프로퍼티를 출력하게 된다.

function printName(person) {
  if (!person) {
    console.log("person의 값이 없습니다.");
    return;
  }
  console.log(person.name);
}

let person = {
  name: "장원영",
};

printName(person); // "장원영"

댓글