Aktualizacja na 2018.10.31
Ten błąd został naprawiony w iOS 12.1, miłego dnia ~
Znalazłem problem ze stanem wartości Array w nowo wydanym Safari na iOS 12, na przykład taki kod:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<title>iOS 12 Safari bugs</title>
<script type="text/javascript">
window.addEventListener("load", function ()
{
let arr = [1, 2, 3, 4, 5];
alert(arr.join());
document.querySelector("button").addEventListener("click", function ()
{
arr.reverse();
});
});
</script>
</head>
<body>
<button>Array.reverse()</button>
<p style="color:red;">test: click button and refresh page, code:</p>
</body>
</html>
Po odświeżeniu strony wartość tablicy jest nadal odwracana. Czy to błąd lub funkcja nowego Safari?
Oto strona demonstracyjna. Spróbuj użyć go z iOS 12 Safari: https://abelyao.github.io/others/ios12-safari-bug.html
javascript
ios
safari
ios12
abelyao
źródło
źródło
Odpowiedzi:
To zdecydowanie BŁĄD! I to jest bardzo poważny błąd.
Błąd wynika z optymalizacji inicjalizatorów tablicowych, w których wszystkie wartości są pierwotnymi literałami. Na przykład, biorąc pod uwagę funkcję:
Wszystkie zwrócone odwołania tablic z wywołań do
buildArray()
linkują do tej samej pamięci, a niektóre metody, takie jak,toString()
będą buforowane swoje wyniki. Zwykle, aby zachować spójność, każda zmienna operacja na takich zoptymalizowanych tablicach spowoduje skopiowanie danych do osobnej przestrzeni pamięci i połączenie z nią; ten wzorzec nazywa się kopiowaniem przy zapisie lub w skrócie CoW.Te
reverse()
metody mutuje tablicy, więc powinno wywołać kopiowanie przy zapisie. Ale tak nie jest, ponieważ oryginalny implementator (Keith Miller z Apple) przegapiłreverse()
przypadek, mimo że napisał wiele przypadków testowych.Ten błąd został zgłoszony firmie Apple 21 sierpnia. Poprawka trafiła do repozytorium WebKit 27 sierpnia i została dostarczona w Safari 12.0.1 i iOS 12.1 30 października 2018 r.
źródło
Napisałem lib, aby naprawić błąd. https://www.npmjs.com/package/array-reverse-polyfill
To jest kod :
źródło
this.length = this.length
) uruchomi Copy On Write, więc zmieni adres pamięci tablicy, a więc poprawi zachowaniereverse
.To jest błąd w zestawie internetowym . Chociaż zostało to rozwiązane na ich końcu, ale nie zostało jeszcze dostarczone z wersją iOS GM. Jedno z rozwiązań tego problemu:
źródło
Wydaje się, że nie jest buforowana, jeśli zmienia się liczba elementów.
Tak mogłem tego uniknąć.
źródło