Đối số mặc định Javascript với phạm vi chặn không thành công chỉ trên iOS


9

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

Trên OS X Chrome, OS X Safari, Android Chrome, Windows Chrome, Windows Firefox và thậm chí Windows Edge, nó cảnh báo "giá trị chính xác". Trên iOS Safari và iOS Chrome, nó thông báo "Không thể tìm thấy biến: val".

Các đoạn mã sau đây đều hoạt động trên iOS:

Không sử dụng đối số mặc định (đoạn 2):

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

Không có chức năng lồng nhau (đoạn 3):

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

Không ghi đè biến (đoạn 4):

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

Chặn phạm vi thay vì chức năng (đoạn 5):

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

Dựa trên đoạn 3, rõ ràng rằng phần valvào arg = valphải xuất phát từ phạm vi cha, không phải phạm vi của hàm bên trong.

Trong đoạn mã đầu tiên, trình duyệt không thể tìm thấy valtrong phạm vi hiện tại, nhưng thay vì kiểm tra phạm vi tổ tiên, nó sử dụng phạm vi con, gây ra vùng chết tạm thời.

Đây có phải là lỗi của iOS hay tôi hiểu nhầm hành vi JS thích hợp?

Lỗi này xảy ra trong đầu ra Webpack + Babel + Terser của chúng tôi, vì vậy chúng tôi không thể viết lại mã để tránh lỗi này.

Câu trả lời:


3

Tôi nghĩ rằng đây là hậu quả không mong muốn của việc triển khai lỗi các giá trị mặc định Param và TDZ của chúng . Tôi nghi ngờ rằng iOS Safari nghĩ rằng bạn đang cố gắng gán cho thứ gì đó bạn chưa khởi tạo.

Để tham khảo - vị trí lỗi:

nhập mô tả hình ảnh ở đây


Giải pháp thay thế 1 Không khởi tạo phạm vi bên trong const w / cùng tên với tham số mặc định & phạm vi bên ngoài

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');
}

Cách giải quyết 2

Force constđể let:

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');
}

Giải pháp thay thế 3 Đừng tái cấp phép const valtrong lần đóng cửa cuối cùng:

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');
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.