틀린 것 잘못된 것들은 올바르게 잡아주시면 감사하겠습니다.
nullish coalescing operator ??
은 nullish한 값(null
혹은 undefined
)을 판별하여 or 연산을 하는 연산자이다.
왼쪽 피연산사가 nullish한 값(null
혹은 undefined
)한 경우에 오른쪽 피연산자를, 그렇지 않은 경우에는 왼쪽 피연산자를 반환한다.
const x = hello ?? hi();
따라서 위의 코드는 아래의 연산과 동일하다.
const x = (hello !== null && hello !== undefined) ?
hello :
hi();
foo
(왼쪽의 피연산자)가 nullish하다면 hi()
를 반환, 그렇지 않다면 hello
를 반환한다.
여기까지만 보면 기존의 or 연산자 ||
와 크게 다름 없어 보이는데, 실제로도 타입스크립트 문서에서도 기본 값으로 사용하는 경우??
가 ||
를 대체할 수 있다고 쓰여있다.
The
??
operator can replace uses of||
when trying to use a default value. For example, the following code snippet tries to fetch the volume that was last saved in localStorage (if it ever was);
-typescript 문서 중-
그리고 아래와 같은 예제 코드가 나와있는데...
function initializeAudio() {
const volume = localStorage.volume || 0.5;
// ...
}
localStorage에 저장된 volume 값이 있으면 해당 값을 변수 volume
에 할당하고 그렇지 않은 경우에 0.5를 할당하라는 or 연산... 그러나 ||
사용 시에는 버그가 발생할 수 있었으니..
자바스크립트의 truty, falsy 값에 혼란을 주는 것들이 몇몇 있다는 것..
대표적으로 빈 문자열 ''
과 숫자 0, NaN
다른 언어 하시는 분들이 자바스크립트에 회의적인 것이.. 이해가 가기도 한다..ㅎㅎ..
??
!== ||
따라서 위의 예제에서 발생할 수 있는 버그는
const volume = localStorage.volume || 0.5;
localStorage.volume
값이 0이라면 falsy 값으로 판단되어 0.5가 할당되는 것이다.
음소거는 반영되지 않는다니... 안돼애..
해당 연산을 nullish operator를 사용하여 아래와 같이 변경한다면
const volume = localStorage.volume ?? 0.5;
localStorage.volume
가 빈 문자열이나 0, NaN
와 같은 falsy값이라 해도 nullish한 경우에만 0.5가 할당될 것이다.
When localStorage.volume is set to 0, the page will set the volume to 0.5 which is unintended.
??
avoids some unintended behavior from 0, NaN and "" being treated as falsy values.
-typescript 문서 중-
실제 falsy 값들로 인해서 의도치 않은 연산이 된 경우가 잦았던 것을 생각해보면 ??
연산자로 확실히 더 명확하게 불필요한 타입들을 걸러낼 수 있게 된 것 같다.
nullish한 값이 들어올 수 있는 경우 null
의 경우에도 undefiend
로 반환시켜 사용하기 위해 아래와 같은 방식으로 null
을 제거할 수 있다.
const x = data ?? undefiend;
null
과 undefined
모두 값이 없음을 나타내는 데이터 타입이긴 하지만 null
은 없는 값임을 할당하여 명시적으로 보여주는 것이므로 undefiend
와는 엄연히 다르다.
실제로 변수 선언 후 값을 할당하지 않으면 undefined
가 할당되어 값이 없음을 나타내지만 null
은 변수에 직접 할당을 해주어야 한다.
let data;
data // undefined
data = null;
data // null
falsy 값들은 !
not 연산자로 묶어서 처리하던 이전의 나.. 반성하라....
Optional chaining ?.
은 .
체이닝과 동일한 기능을 하는데 다른 점은 참조 값이 nullish한 경우에 에러를 뿜지 않고 undefiend
를 반환한다.
이것은 참조가 누락될 가능성이 있는 경우 연결된 속성으로 접근할 때 더 짧고 간단한 표현식이 생성된다. 어떤 속성이 필요한지에 대한 보증이 확실하지 않는 경우 객체의 내용을 탐색하는 동안 도움이 될 수 있다.
-MDN 문서 중-
const person = {
name: undefined
};
person.name // undefined
person.name.firstName // Error! Uncaught TypeError: Cannot read property 'firstName' of undefined
person.name?.firstName // undefined
error가 아닌 undefined
를 반환하므로 코드를 간략히 하는데 요긴하게 사용되며, 나아가 일종의 에러 핸들링의 역할도 한다.
<div>
{data && data.dogs && data.dogs.map(dog => (
<option key={dog.id} value={dog.breed}>
{dog.breed}
</option>
))}
</div>
위의 로직는 아래의 동일하다.
<div>
{data?.dogs?.map(dog => (
<option key={dog.id} value={dog.breed}>
{dog.breed}
</option>
))}
</div>
someInterface
내에 customMethod
가 없는 경우!
const someInterface = {
otherMethod: () => {
return 'otherMethod called!';
}
};
someInterface.customMethod(); // Error! Uncaught TypeError: someInterface.custromMethod is not a function
someInterface.customMethod?.(); // undefined
someInterface
내에 customMethod
가 있는 경우!
const someInterface = {
customMethod: () => {
return 'customMethod called!';
}
};
someInterface.customMethod.(); // 'customMethod called!'
someInterface.customMethod?.(); // 'customMethod called!'
const customer = {
name: "Carl",
details: { age: 82 }
};
const customerCity = customer?.city ?? "Unknown city";
console.log(customerCity); // Unknown city
apollo 쿼리를 사용하여 데이터를 받아오는 경우엔 아래와 같이 핸들링 할 수 있다.
function Dogs({ onDogSelected }) {
const { loading, error, data } = useQuery(GET_DOGS);
const dogs = data?.dogs ?? [];
if (loading) return 'Loading...';
if (error) return `Error! ${error.message}`;
return (
<select name="dog" onChange={onDogSelected}>
{dogs?.map(dog => (
<option key={dog.id} value={dog.breed}>
{dog.breed}
</option>
))}
</select>
);
}
The nullish coalescing operator is another upcoming ECMAScript feature that goes hand-in-hand with optional chaining, and which our team has been involved with championing in TC39.
-typescript 문서 중-
입사 후 타입스크립트를 사용하면서 처음 접한 연산자들라 타입스크립트에서만 사용되는 건줄 알았는데 optional chaining과 함께 새로운 자바스크립트의 기능이었다.. 읍! 재밌다
(0 || undefined) ?? 'yejinh'
('0' && null) ?? 'yejinh'
null ?? (undefined && 0)
null ?? undefined ?? 0
const obj = {
name: ''
};
obj.name ?? 0
obj.name || 0
obj?.age ?? 0
(obj.name ?? 0) && null
obj.name || (0 ?? null)
각각의 연산은 무엇을 반환할까요 ?
정답은 개발자도구 창에서 직접 확인해보세요오오
프로미스에 대한 것 검색하다 쉽게 풀어 쓴 글 보고 감탄! 받아 다른 글들도 찾아서 보는 중입니다. 개념 설명을 참 잘하세요! 감사드립니다