JS 리팩토링 주의 사항: 옵셔널 체이닝으로 변환하면 코드가 깨질 수 있는 5가지 방법
.?
는 개체를 사용할 수 있을 때 개체 속성 값을 반환하고 그렇지 않으면 undefined
를 반환합니다. 표준.
연결 연산자와 유사하며 개체가 정의되어 있는지(즉, nullish 아님) 확인이 추가되었습니다.선택적 연결 연산자를 사용하면 연결된 개체 중 일부가
null
또는 undefined
일 수 있는 경우 연결된 개체의 간결하고 안전한 체인을 작성할 수 있습니다. ES2020에 optional chaining이 도입되기 전에 &&
연산자는 객체가 사용 가능한지 확인하는 데 자주 사용되었습니다( obj && obj.value
).선택적 연결 패턴을 사용하여 기존 검사를 종종 단순화할 수 있습니다.
obj && obj.property
는 obj?.property
가 된다obj != null && obj.property
는 obj?.property
가 된다obj != null ? obj.property : undefined
는 obj?.property
가 된다arr && arr[i]
는 arr?.[i]
가 된다f && f()
는 f?.()
가 된다그러나 옵셔널 체이닝으로 리팩토링하면 버그가 발생할 수 있는 몇 가지 경우가 있습니다.
null 값에 대한 선택적 연결 단락(다른 거짓 값에는 해당되지 않음)
a && a.b
가 a?.b
로 대체되면 falsy 값을 가질 수 있는 유형에 대한 실행이 변경됩니다. 이는 결과 값과 식의 유형이 선택적 연결과 다를 수 있음을 의미합니다.다음 스니펫은 몇 가지 예를 보여줍니다.
function test(value) {
console.log(`${value && value.length}, ${value?.length}`);
}
test(undefined); // undefined, undefined
test(null); // null, undefined
test(true); // undefined, undefined
test(false); // false, undefined
test(1); // undefined, undefined
test(0); // 0, undefined
test({}); // undefined, undefined
test([]); // 0, 0
test({ length: "a" }); // a, a
test(''); // , 0
test(NaN); // NaN, undefined
거짓이지만 nullish 이 아닌 빈 문자열은 특히 문제가 될 수 있습니다. 다음은 선택적 연결을 도입하여 문제를 일으킬 수 있는 예입니다.
// without optional chaining
if (s && s.length === 0) {
// not called for the empty string
// (e.g., legacy code that works this way)
}
// with optional chaining
if (s?.length === 0) {
// called for the empty string
// (potentially introducing undesired behavior)
}
선택적 연결은 null에 대한 결과를 정의되지 않음으로 변경합니다.
null로
a?.b
를 호출하면 결과는 undefined
입니다. 그러나 a && a.b
의 경우 결과는 null
입니다.선택적 연결은 부작용이 있는 호출 수에 영향을 줄 수 있습니다.
예를 들어 변경을 고려하십시오.
f() && f().a;
~ 안으로
f()?.a;
&&
로 , f
를 한두 번 호출합니다. 그러나 선택적 연결f
을 사용하면 한 번만 호출됩니다. f
에 부작용이 있는 경우 이 부작용이 다른 횟수로 호출되어 잠재적으로 동작이 변경되었을 수 있습니다. 이 동작은 함수 및 메서드 호출뿐만 아니라 잠재적으로 부작용이 있을 수 있는 getter에도 적용됩니다.TypeScript는 'void' 유형의 선택적 연결을 지원하지 않습니다.
TypeScript does not support optional chaining for
void
, 해당 JavaScript 코드가 작동하더라도 이벤트가 발생합니다.type Input = void | {
property: string
};
function f(input: Input) {
// this works:
console.log(input && input.property);
// this breaks because void is not undefined in TypeScript:
console.log(input?.property);
}
이전 브라우저 및 JavaScript 엔진은 선택적 연결을 지원하지 않습니다.
선택적 연결은 ES2020 기능입니다. 모든 최신 브라우저 및 Node 14+에서 지원되지만 이전 브라우저 및 Node 버전의 경우 변환이 필요할 수 있습니다( compatibility ).
Reference
이 문제에 관하여(JS 리팩토링 주의 사항: 옵셔널 체이닝으로 변환하면 코드가 깨질 수 있는 5가지 방법), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/p42/5-ways-that-converting-to-optional-chaining-can-break-your-javascript-code-153b텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)