선택 가능 한 체인 으로 코드 를 재 구성 하 는 방법 | ES 2020
24446 단어 자바 script
우선
(optional-chaining)
이 무엇 인지 ES2020
에 도 입 된 새로운 특성 으로 typescript v3.7
에서 도 이미 지지 했다.코드 에 만
foo.bar.baz()
쓰 고 foo
존재 하 는 지 확인 하지 않 고 foo.bar
존재 하 는 지 확인 한 다음 foo.bar.baz
존재 하 는 지 확인 하고 foo?.[bar]
존재 하 는 지 확인 하지 않 으 면 이상 을 받 을 수 있다 는 것 을 알 아야 한다.그래서 당신 의 코드 는 다음 과 유사 해 야 합 니 다:if (foo && foo.bar && foo.bar.baz) {
foo.bar.baz();
}
또는:
foo && foo.bar && foo.bar.baz && foo.bar.baz();
하지만 선택 할 수 있 는 체인 이 있 으 면 직접 이렇게 할 수 있 습 니 다.
foo?.bar?.baz?.()
이것 은 정상 적 인 속성 접근, 괄호
foo?.()
, 심지어 함수 호출 foo && foo.bar
을 지원 합 니 다.선택 가능 한 체인 은 다른 많은 코드 를 간소화 할 수 있 을 뿐만 아니 라 주의해 야 할 부분도 있다.
어디 를 재 구성 합 니까?
만약 당신 이 당신 의 코드 를 재 구성 하기 로 결정 했다 면 무엇 을 찾 으 시 겠 습 니까?
물론 뚜렷 한 것 은
foo?.bar
이 있 었 고 if
로 바 뀌 었 다.앞에서 말 한
Array.isArray(foo)
문장의 코드 도 있다.또 다른 경우 도 있다.
삼원 연산 자
foo ? foo.bar : defaultValue
재 구성 후:
foo?.bar || defaultValue
또는 ES 2020 의 또 다른 연산 자, 빈 값 으로 연산 자 (Nullish Coalescing Operator) 를 합 칩 니 다.
foo?.bar ?? defaultValue
배열 검사
if (foo.length > 3) {
foo[2]
}
재 구성 후:
foo?.[2]
이것 은 실제 배열 검 사 를 대체 할 수 없습니다. 예 를 들 어
foo
.정규 일치
let match = "#C0FFEE".match(/#([A-Z]+)/i);
let hex = match && match[1];
혹은
let hex = ("#C0FFEE".match(/#([A-Z]+)/i) || [,])[1];
재 구성 후:
let hex = "#C0FFEE".match(/#([A-Z]+)/i)?.[1];
속성 검사
if (element.prepend) element.prepend(otherElement);
재 구성 후:
element.prepend?.(otherElement);
남용 하지 마라
이러한 코드 를 재 구성 하고 싶 을 수도 있 지만:
if (foo) {
something(foo.bar);
somethingElse(foo.baz);
andOneLastThing(foo.yolo);
}
다음으로 전환:
something(foo?.bar);
somethingElse(foo?.baz);
andOneLastThing(foo?.yolo);
그 러 지 마.JS 가 한 번 이 아 닌 운행 중 검사
foo
를 세 번 하 게 하기 때문이다.성능 에 있어 서 그다지 중요 하지 않다 고 생각 할 수도 있 지만 코드 를 읽 는 사람 에 게 도 똑 같은 중복 이 존재 할 수 있다. 그들 은 한 번 이 아니 라 심리 적 으로 세 번 foo
에 대한 검 사 를 처리 해 야 한다.만약 그들 이 다른 문장 에 Uncaught SyntaxError: Invalid left-hand side in assignment
의 속성 을 사용 하려 면 기 존의 조건 을 사용 하 는 것 이 아니 라 다른 검 사 를 추가 해 야 한다.주의 사항
성명 전에 검사 해 야 할 상황
다음 코드 를:
if (foo && foo.bar) {
foo.bar.baz = someValue;
}
다음으로 재 구성:
foo?.bar?.baz = someValue;
그러나 이렇게 하면 실 수 를 할 수 있다.예 를 들 어 아래 코드 를:
if (this.bar && this.bar.edit) {
this.bar.edit.textContent = this._("edit");
}
다음으로 재 구성:
if (this.bar?.edit) {
this.bar.edit.textContent = this._("edit");
}
코드 가 다시 구 성 될 때 까지 모든 것 이 괜 찮 았 습 니 다.
this.bar?.edit?.textContent = this._("edit");
이것 은 이러한 이상 을 던 질 것 이다.
ESLint
.그래서 당신 은 여전히 조건 이 필요 합 니 다. 이러한 오류 가 코드 를 실행 한 후에 발생 하 는 것 을 방지 하기 위해 서 ?.
를 사용 할 수 있 습 니 다.?.
위 치 를 잘못 놓 거나 잊 어 버 리 기 ?.
주의해 야 할 것 은 선택 할 수 있 는 체인 이 있 는 긴 체인 을 재 구성 할 때 첫 번 째 체인 뒤에 여러 개 undefined
를 삽입 해 야 한 다 는 것 이다. 그렇지 않 으 면 선택 할 수 있 는 체인 이 되 돌아 오 면 코드 가 틀 릴 것 이다.혹은 당신 이
?.
자 리 를 잘못 놓 았 기 때 문 입 니 다.예 를 들 어 다음 코드:
this.children[index]? this.children[index].element : this.marker
다음으로 재 구성:
this.children?.[index].element ?? this.marker
그러면 당신 은 이러한 오 류 를 얻 을 수 있 습 니 다.
TypeError: Cannot read property 'element' of undefined.
이렇게 하 나 를 잊 어 버 려 서 ?.
발생 한 것 입 니 다.this.children?.[index]?.element ?? this.marker
이렇게 하면 가능 하지만 재 구성 전의 코드 를 돌 이 켜 보면 하나
?.
는 불필요 하 다.this.children[index]?.element ?? this.marker
배열 의 길이 검 사 를 선택 가능 한 체인 으로 대체 할 때 성능 에 영향 을 줄 수 있 습 니 다. 배열 의 크로스 오 버 접근 은 V8 실행 코드 의 효율 에 영향 을 줄 수 있 기 때 문 입 니 다.
버그 를 일 으 킬 수 있 으 니 조심 하 세 요.
당신 이 어느 정도 재 구성 한 후에 일부 지역 에서 선택 가능 한 체인 만 도입 하기 쉬 울 것 입 니 다. 실제로 코드 의 역할 을 바 꾸 어 알 아차 리 기 어 려 운 bug 를 야기 할 것 입 니 다.
null vs. undefined
가장 흔 한 경 우 는
foo && foo.bar
을 foo?.bar
로 교체 하 는 것 으로 보인다.대부분의 경우 이 두 함수 의 작업 원 리 는 같 지만 모든 상황 이 다 그런 것 은 아니다.foo
가 null
일 때 전 자 는 null
로 돌아 가 고 후 자 는 undefined
로 돌아간다.이 는 정확 한 구분 상황 에서 bug 가 발생 할 수 있 습 니 다. 이것 은 이러한 상황 에서 가장 흔히 볼 수 있 는 bug 를 재 구성 하 는 것 입 니 다.전 등급 검사
예 를 들 어 아래 코드 를:
if (foo && bar && foo.prop1 === bar.prop2) { /* ... */ }
다음으로 전환:
if (foo?.prop1 === bar?.prop2) { /* ... */ }
첫 번 째 상황 에서 foo 와 bar 가 모두 진짜 일 때 조건 만 이 진실 이다.그러나 두 번 째 경우
foo
와 bar
모두 undefined
라면 조건 도 진짜 일 것 이다.연산 자 우선 순위
주의해 야 할 것 은 선택 가능 한 체인 의 우선 순위 가
&&
보다 높다 는 것 이다.특히 평등 연산 자 &&
와 평등 연산 자 를 포함 하 는 표현 식 을 재 구성 할 때, 평등 연산 자 는 ?.
와 &&
에 비해 우선 순위 가 전자 보다 낮 고 후자 보다 높 기 때문에 추가 적 인 주의 가 필요 하 다.if (foo && foo.bar === baz) { /* ... */ }
여기
baz
누구 랑 비교 해요?foo.bar
아니면 foo && foo.bar
?&&
의 우선 순위 가 ===
보다 낮 기 때문에 다음 과 같다.if (foo && (foo.bar === baz)) { /* ... */ }
위의 코드 에서 만약
foo
이 가짜 값 이 라면 조건 은 영원히 실 행 될 수 없다.그러나 우리 가 이 를 선택 가능 한 체인 의 형식 으로 재 구성 하면 비교 foo && foo.bar
와 baz
가 된다.if (foo?.bar === baz) { /* ... */ }
한 가지 뚜렷 한 문 제 는
baz
이 undefined
일 때 우 리 는 foo
이 nullish
일 때 조건문 에 들 어 갈 수 있다 는 것 이다. 이것 은 우리 의 취지 와 어 긋 난다.또 다른 더 나 쁜 상황 은 부등식 조작 부호 가 나타 날 때 평등 조작 부호 와 같은 우선 순 위 를 가지 기 때문이다.예 를 들 면:
if (foo && foo.bar !== baz) { /* ... */ }
다음으로 전환:
if (foo?.bar !== baz) { /* ... */ }
지금 은
baz
아니 undefined
가 아니 라 foo
가 nullish
이면 조건문 에 들어간다!반환 문
반환 문 구 를 재 구성 할 때, 당신 은 이러한 교 체 를 조심해 야 합 니 다.
if (foo && foo.bar) {
return foo.bar();
}
다음으로 전환:
return foo?.bar?.();
첫 번 째 상황 에서 코드 는 조건 부 로 돌아 오지 만 두 번 째 상황 에서 코드 는 항상 돌아온다.만약 조건 이 함수 중의 마지막 문장 이 라면 이것 은 아무런 문제 가 없 지만 그렇지 않 으 면 제어 절 차 를 바 꿀 것 이다.
마찬가지 로 선택 가능 한 체인 도 bug 를 복구 할 수 있 습 니 다!
이 코드 를 보 세 요.
/**
* Get the current value of a CSS property on an element
*/
getStyle: (element, property) => {
if (element) {
var value = getComputedStyle(element).getPropertyValue(property);
if (value) {
return value.trim();
}
}
},
이 코드 의 오 류 를 발 견 했 습 니까?만약
value
이 빈 문자열 이 라면 (문맥 에 따라 그 럴 수 있 습 니 다) 함 수 는 undefined
로 돌아 갑 니 다. 빈 문자열 은 가짜 값 이기 때 문 입 니 다.우 리 는 선택 가능 한 체인 을 사용 하여 이 문 제 를 해결한다.if (element) {
var value = getComputedStyle(element).getPropertyValue(property);
return value?.trim();
}
현재
value
가 빈 문자열 이 라면 빈 문자열 을 되 돌려 주 는 것 을 지원 하고 value
가 nullish
일 때 만 되 돌려 줍 니 다 undefined
.주: 여기에 더 많은 재 구성 실례 가 기록 되 어 있다
원문 - repositing - optional - chaining - to - a - large - codebase - lesson - learned
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Thymeleaf 의 일반 양식 제출 과 AJAX 제출텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.