다른 많은 언어와 달리, JavaScript에는 (의미 있는) 값이 없음을 나타내는 서로 다른 두 가지 요소가 있어요.
바로 null과 undefined예요.
원시 값 null은 모든 타입의 변수에서 의도적으로 "빈 값"을 나타낼 때 사용해요.
let name = null;
// name is intentionally set to "empty" because it is not
// available
일치 연산자 ===를 사용하면 변수가 null인지 확인할 수 있어요.
let name = null;
name === null;
// => true
값을 할당하지 않은 변수는
undefined타입이에요.1
즉, null은 빈 값(그래도 여전히 값)을 나타내지만, undefined는 값이 완전히 없음을 나타내요. 🤯
undefined는 다양한 상황에서 나타나요.
undefined예요.undefined를 얻게 돼요.undefined예요.undefined예요.let name;
console.log(name);
// => undefined
일치 연산자 ===를 사용하면 변수가 undefined인지 확인할 수 있어요.
let name;
name === undefined;
// => true
객체에서 중첩된 값을 가져오려고 하는데 부모 키가 존재하지 않으면, JavaScript는 오류를 발생시켜요.
이를 쉽게 피하기 위해 2020년에 옵셔널 체이닝이 언어 명세에 추가됐어요.
옵셔널 체이닝 연산자 ?.를 사용하면 부모가 null 또는 undefined가 아닐 때만 JavaScript가 중첩된 키에 접근하도록 할 수 있어요.
그렇지 않으면 undefined가 반환돼요.
const obj = {
address: {
street: 'Trincomalee Highway',
city: 'Batticaloa',
},
};
obj.address.zipCode;
// => undefined
obj.residence.street;
// => TypeError: Cannot read property 'street' of undefined
obj.residence?.street;
// => undefined
변수가 null이거나 undefined일 때(그리고 그럴 때만) 기본값을 적용하고 싶은 상황이 있어요.
이를 해결하기 위해 2020년에 Nullish 병합 연산자 ??가 도입됐어요.
왼쪽 피연산자가 null 또는 undefined일 때만 오른쪽 피연산자를 반환해요.
그렇지 않으면 왼쪽 피연산자가 반환돼요.
let amount = null;
amount = amount ?? 1;
// => 1
amount = 0;
amount = amount ?? 1;
// => 0
[1] Undefined, MDN. (2021). https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined (2021년 6월 4일 확인).
놀이공원의 IT 시스템 일부를 만들고 유지 관리하는 일을 맡게 됐어요. 특히 방문객과 티켓을 관리하는 프로그램을 담당해요.
먼저 시스템에 새 방문객을 만들어요. 그다음에는 티켓을 취소하는 함수를 만들어요. 3번과 4번 과제에서는 위조를 방지하는 티켓 추적 시스템을 다뤄요. 마지막으로 새로운 법적 요구 사항에 맞춰 시스템을 조정하는 작업을 맡아요.
방문객이 놀이공원에 처음 오면 터미널에 이름과 나이를 입력하고 약관에 동의해서 등록해야 해요.
물론 티켓도 사야 해요.
각 티켓에는 H32AZ123 같은 식별자가 있어요.
세 개의 인자를 받는 createVisitor 함수를 작성해요.
이 함수는 이 정보를 담은 객체를 반환해야 해요.
객체의 키는 name, age, ticketId여야 해요.
createVisitor('Verena Nardi', 45, 'H32AZ123');
// => { name: 'Verena Nardi', age: 45, ticketId: 'H32AZ123' }
사람들이 놀이공원을 떠나면 티켓이 취소돼요. 다시 오면 새 티켓을 사야 해요. 단골 방문객의 시간을 아끼기 위해, 등록은 한 번만 하면 되고 방문객 정보는 다음 방문을 위해 보관돼요.
즉, 방문객이 공원을 떠날 때는 티켓만 무효화되고 방문객 객체의 나머지 부분은 그대로 유지되어야 해요.
방문객 객체를 받아 티켓 식별자를 null로 설정하고 그 뒤에 객체를 반환하는 revokeTicket 함수를 구현해요.
const visitor = {
name: 'Verena Nardi',
age: 45,
ticketId: 'H32AZ123',
};
revokeTicket(visitor);
// => { name: 'Verena Nardi', age: 45, ticketId: null }
위조를 막기 위해 티켓 식별자는 고유해요. 티켓이 인쇄되면 그 식별자가 시스템의 객체에 키로 추가되어 추적할 수 있어요.
티켓이 방문객에게 팔리기 전에는 티켓 추적 객체에 null 값으로 저장돼요.
방문객에게 팔리면 방문객의 이름이 값으로 할당돼요.
직원이 티켓의 유효성에 의문이 들면 시스템에서 티켓 상태를 확인해야 해요.
추적 객체와 티켓 식별자를 인자로 받는 ticketStatus 함수를 구현해요.
이 함수는 다음 결과 중 하나를 반환해야 해요.
'unknown ticket id'
'not sold'
'sold to {name}'. 여기서 {name}은 방문객의 이름이에요const tickets = {
'0H2AZ123': null,
'23LA9T41': 'Verena Nardi',
};
ticketStatus(tickets, 'RE90VAW7');
// => 'unknown ticket id'
ticketStatus(tickets, '0H2AZ123');
// => 'not sold'
ticketStatus(tickets, '23LA9T41');
// => 'sold to Verena Nardi'
얼마 지나서 직원들로부터 티켓 상태를 한눈에 더 쉽게 이해할 수 있게 해달라는 피드백을 받았어요. 방문객의 이름이나 티켓이 유효하지 않다는 것, 둘 중 하나만 보고 싶어 해요.
3번 과제의 ticketStatus와 같은 인자를 받는 simpleTicketStatus 함수를 작성해요.
이 함수는 두 가지 결과 중 하나만 반환해요.
'invalid ticket !!!'
const tickets = {
'0H2AZ123': null,
'23LA9T41': 'Verena Nardi',
};
simpleTicketStatus(tickets, '23LA9T41');
// => 'Verena Nardi'
simpleTicketStatus(tickets, '0H2AZ123');
// => 'invalid ticket !!!'
simpleTicketStatus(tickets, 'RE90VAW7');
// => 'invalid ticket !!!'
새로운 법적 요구 사항 때문에, 새로 만들어지는 방문객 객체에는 이제 사용자가 동의한 "일반 이용약관"(GTC)에 대한 자세한 정보도 들어 있어요. 아래에서 새 방문객 객체의 예를 볼 수 있어요.
이제 놀이공원의 계산원은 방문객이 새로운 버전의 GTC에 서명해야 하는지 확인해야 해요.
이를 위해 방문객 객체를 인자로 받아 GTC 버전이 있으면 반환하는 gtcVersion 함수를 구현해요.
버전 정보가 없으면 아무것도 반환하지 않아요.
const visitorNew = {
name: 'Verena Nardi',
age: 45,
ticketId: 'H32AZ123',
gtc: {
signed: true,
version: '2.1',
},
};
gtcVersion(visitorNew);
// => '2.1'
const visitorOld = {
name: 'Verena Nardi',
age: 45,
ticketId: 'H32AZ123',
};
gtcVersion(visitorOld);
// => undefined
Exercism에 가입하고 JavaScript 트랙을 개념 37개연습 문제 159개, 그리고 실제 사람의 멘토링과 함께 배우고 익혀 보세요. 모두 무료예요.