선택 가능 한 체인 으로 코드 를 재 구성 하 는 방법 | ES 2020

24446 단어 자바 script
목차
  • 어디 를 재 구성 합 니까?
  • 삼원 연산 자
  • 배열 검사
  • 정규 일치
  • 속성 검사
  • 남용 하지 마 세 요
  • 주의사항
  • 성명 전에 검사 해 야 할 상황
  • 그렇지?위 치 를 잘못 놓 거나 잊 어 버 리 거나...?
  • 버그 를 일 으 킬 수 있 는 상황 을 조심해 야 한다
  • null vs. undefined
  • 전체 검사
  • 연산 자 우선 순위
  • 반환 문
  • 마찬가지 로 선택 가능 한 체인 도 bug 를 복구 할 수 있 습 니 다!

  • 우선 (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.barfoo?.bar 로 교체 하 는 것 으로 보인다.대부분의 경우 이 두 함수 의 작업 원 리 는 같 지만 모든 상황 이 다 그런 것 은 아니다.foonull 일 때 전 자 는 null 로 돌아 가 고 후 자 는 undefined 로 돌아간다.이 는 정확 한 구분 상황 에서 bug 가 발생 할 수 있 습 니 다. 이것 은 이러한 상황 에서 가장 흔히 볼 수 있 는 bug 를 재 구성 하 는 것 입 니 다.
    전 등급 검사
    예 를 들 어 아래 코드 를:
    if (foo && bar && foo.prop1 === bar.prop2) { /* ... */ }
    

    다음으로 전환:
    if (foo?.prop1 === bar?.prop2) { /* ... */ }
    

    첫 번 째 상황 에서 foo 와 bar 가 모두 진짜 일 때 조건 만 이 진실 이다.그러나 두 번 째 경우 foobar 모두 undefined 라면 조건 도 진짜 일 것 이다.
    연산 자 우선 순위
    주의해 야 할 것 은 선택 가능 한 체인 의 우선 순위 가 && 보다 높다 는 것 이다.특히 평등 연산 자 && 와 평등 연산 자 를 포함 하 는 표현 식 을 재 구성 할 때, 평등 연산 자 는 ?.&& 에 비해 우선 순위 가 전자 보다 낮 고 후자 보다 높 기 때문에 추가 적 인 주의 가 필요 하 다.
    if (foo && foo.bar === baz) { /* ... */ }
    

    여기 baz 누구 랑 비교 해요?foo.bar 아니면 foo && foo.bar?&& 의 우선 순위 가 === 보다 낮 기 때문에 다음 과 같다.
    if (foo && (foo.bar === baz)) { /* ... */ }
    

    위의 코드 에서 만약 foo 이 가짜 값 이 라면 조건 은 영원히 실 행 될 수 없다.그러나 우리 가 이 를 선택 가능 한 체인 의 형식 으로 재 구성 하면 비교 foo && foo.barbaz 가 된다.
    if (foo?.bar === baz) { /* ... */ }
    

    한 가지 뚜렷 한 문 제 는 bazundefined 일 때 우 리 는 foonullish 일 때 조건문 에 들 어 갈 수 있다 는 것 이다. 이것 은 우리 의 취지 와 어 긋 난다.
    또 다른 더 나 쁜 상황 은 부등식 조작 부호 가 나타 날 때 평등 조작 부호 와 같은 우선 순 위 를 가지 기 때문이다.예 를 들 면:
    if (foo && foo.bar !== baz) { /* ... */ }
    

    다음으로 전환:
    if (foo?.bar !== baz) { /* ... */ }
    

    지금 은 baz 아니 undefined 가 아니 라 foonullish 이면 조건문 에 들어간다!
    반환 문
    반환 문 구 를 재 구성 할 때, 당신 은 이러한 교 체 를 조심해 야 합 니 다.
    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 가 빈 문자열 이 라면 빈 문자열 을 되 돌려 주 는 것 을 지원 하고 valuenullish 일 때 만 되 돌려 줍 니 다 undefined.
    주: 여기에 더 많은 재 구성 실례 가 기록 되 어 있다
    원문 - repositing - optional - chaining - to - a - large - codebase - lesson - learned

    좋은 웹페이지 즐겨찾기