iOS에서만 블록 범위가 지정된 자바 스크립트 기본 인수가 실패합니다.


9

try {
  const val = 'correct value';
  (() => {
    ((arg = val) => {
      const val = 'ignored value';
      alert(arg);
    })();
  })();
} catch (err) {
  alert(err.message || 'Unknown error');
}

OS X 크롬 OS X 사파리, 안드로이드 크롬, 윈도우 크롬, 윈도우 파이어 폭스,과에 심지어 윈도우 가장자리, 그것은 "올바른 값"을 알려줍니다. iOS Safari 및 iOS Chrome에서는 "변수를 찾을 수 없음 : val"이라고 경고합니다.

다음 스 니펫은 모두 iOS에서 작동합니다.

기본 인수를 사용하지 않습니다 (스 니펫 2) :

try {
  const val = 'correct value';
  (() => {
    alert(val);
    (() => {
      const val = 'wrong value';
    })();
  })();
} catch (err) {
  alert(err.message || 'Unknown error');
}

중첩 함수가 없습니다 (스 니펫 3) :

try {
  const val = 'correct value';
  ((arg = val) => {
    const val = 'ignored value';
    alert(val || 'wrong value');
  })();
} catch (err) {
  alert(err.message || 'Unknown error');
}

변수를 재정의하지 않음 (스 니펫 4) :

try {
  const val = 'correct value';
  (() => {
    ((arg = val) => {
      alert(arg);
    })();
  })();
} catch (err) {
  alert(err.message || 'Unknown error');
}

기능 대신 블록 범위 (스 니펫 5) :

try {
  const val = 'correct value';
  {
    ((arg = val) => {
      const val = 'ignored value';
      alert(arg);
    })();
  }
} catch (err) {
  alert(err.message || 'Unknown error');
}

스 니펫 3에 따르면 valin arg = val은 내부 함수의 범위가 아니라 부모 범위에서 가져와야합니다.

첫 번째 스 니펫에서는 브라우저가 val현재 범위에서 찾을 수 없지만 조상 범위를 확인하는 대신 하위 범위를 사용하므로 일시적인 데드 존이 발생합니다.

이것이 iOS 버그입니까, 아니면 올바른 JS 동작을 오해하고 있습니까?

이 버그는 Webpack + Babel + Terser 출력에서 ​​발생하므로이 버그를 피하기 위해 코드를 다시 작성할 수는 없습니다.

답변:


3

나는 이것이 Param 기본값과 TDZ 의 버그가있는 구현의 원치 않는 결과라고 생각합니다 . iOS Safari가 아직 초기화하지 않은 것에 할당하려고한다고 생각합니다.

참고로 오류 위치 :

여기에 이미지 설명을 입력하십시오


해결 방법 1 기본 매개 변수 및 외부 범위와 동일한 이름으로 내부 범위 구성을 초기화하지 마십시오.

try {
    const val = 'correct value';
    (() => {
        ((arg = val) => {
            const val_ = 'ignored value';       // <----
            alert(arg);
        })();
    })();
} catch (err) {
    console.error(err);
    console.error('msg', err.message || 'Unknown error');
}

해결 방법 2

강제 constlet:

try {
    let val = 'correct value';                 // <----
    (() => {
        ((arg = val) => {
            const val = 'ignored value';
            alert(arg);
        })();
    })();
} catch (err) {
    console.error(err);
    console.error('msg', err.message || 'Unknown error');
}

해결 방법 3const val 가장 안쪽 클로저에서 다시 초기화하지 마십시오 .

try {
    const val = 'correct value';
    (() => {
        ((arg = val) => {
            // const val = 'ignored value';      // <--
            alert(arg);
        })();
    })();
} catch (err) {
    console.error(err);
    console.error('msg', err.message || 'Unknown error');
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.