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

[자바스크립트] primitive, 그 중에서도 null 에 대하여

by 핸디(Handy) 2021. 2. 17.

 

null 은 자바스크립트의 원시값(primitive) 중 하나로, 어떤 값이 의도적으로 비어있음을 표현하여 boolean 연산에서는 false 로 취급하는 값입니다.

null 에 대해 깊게 들어가기 전에 원시값(primitive)에 대해 간략히 설명하고 넘어가겠습니다.

In JavaScript, a primitive (primitive value, primitive data type) is data that is not an object and has no methods. There are 7 primitive data types: string, number, bigint, boolean, undefined, symbol, and null.

MDN 공식 사이트를 보면 자바스크립트에서는 7개의 원시값(primitive)이 있다고 되어있습니다.

이 원시값들은 Ojbect도 아니고, Method도 없습니다. 또한 모든 원시값은 불변(immutable)입니다. 이 불변에 대해 코드로 살펴보겠습니다.

// string method를 string 자체를 바꾸지 못합니다
let javascript = "immutable";
console.log(javascript); // immutable

javascript.toUpperCase(); 
console.log(javascript);   //  immutable

     

// array method는 array 자체를 바꿀수 있습니다.
let javascript = [];
console.log(javascript); // []

javascript.push("immutable");
console.log(javascript);   // ["immutable"]

 

let javascript = "immutable";
javascript = javascript.toUpperCase(); 
console.log(javascript);   //  IMMUTABLE

단 위의 경우는 상황이 다릅니다. 원시값을 바꾼 것이 아니고 원시값을 변수에 다시 할당해준 것이기 때문입니다.

A primitive can be replaced, but it can't be directly altered.

developer.mozilla.org/en-US/docs/Glossary/Primitive


다시 본론으로 돌아와 null 에 대해 설명을 이어가겠습니다.

null은 undefined와 비슷하면서 다른 점이 있습니다.

비슷한 점은 둘다 falsy라는 것이라 다른 점이라면 세부적인 의미 차이입니다.

// 정의되지 않고 초기화된 적도 없는 javascript
javascript; //ReferenceError: javascript is not defined

// 정의됬지만 값이나 자료형이 존재하지 않는 javascript
let javascript = null;
javascript; //null
typeof null          // "object"
typeof undefined     // "undefined"
null === undefined   // false
null  == undefined   // true
null === null        // true
null == null         // true
!null                // true
isNaN(1 + null)      // false
isNaN(1 + undefined) // true

위에 코드를 보시면 알겠지만 null과 undefined를 구별하려고 사용할 때 상당히 까다롭습니다. 예상치 못한 버그의 근원이 되기도 합니다.

null를 반환하지 마라. null를 전달하지 말라
호출자가 실수로 넘기는 null를 적절히 처리하는 방법은 없다. 그렇다면 애초에 null를 넘기지 못하도록 금지하는 정책이 합리적

로버트C.마틴의 클린코드 p.140

실제로 업무상에 다음과 같은 상황이 있습니다.

let title = {
	textSize : 10,
	textColor : "black"
}

title의 text에 관한 정보를 담은 변수입니다. 하지만 title이 없어져야 하는 경우가 생깁니다.

그럴 때는 하나의 변수를 추가하는 게 필요 없음을 나타나는 게 좋을까요?

let title = {
	textSize : 10,
	textColor : "black",
    necessity : false
}

직관적이긴 합니다만 사용 여부에 따라 necessity를 계속 바꿔줘야 하고 property가 추가된 것도 별로입니다. 

그렇다면 null 은 어떨까요?

title = null;

title을 안 쓰는 상황에서 title에 null를 대입하는 것입니다. 이러면 의미가 확고해집니다.
title은 있는 속성이지만 안 쓰겠다는 의미가요.


아래는 제가 실제로 작성했던 코드를 간략화한 것입니다.

methodA(title) {
  if(title == undefined) {
      title = getDefaultTitle(); // { textSize:10, textColor : "black"}
  }
  if(title == null) {
      disableTitle();
  }
}

보면 title이 undefined면 기본값을 가져와 할당해주고 null이라면 title 속성을 disable 시키는 methodA 가 있습니다.

하지만 이 코드에서는 disableTitle() 함수가 돌일이 없습니다. 왜냐하면

title 변수가 undefined, null일 때 둘 다 falsy이기 때문에 무조건 기본값을 얻게 되기 때문입니다.

따라서 아래와 같이 ==(동등연산자) 대신 ===(일치연산자)를 써서 수정해줘야 했습니다.

methodA(title) {
  if(title === undefined) {
      title = getDefaultTitle(); // { textSize:10, textColor : "black"}
  }
  if(title === null) {
      disableTitle();
  }
}

둘의 차이점에 대해 확실히 모르고 의미를 정확히 정하고 사용하지 않아 발생한 일이었습니다.

 

댓글