Update am 31.10.2018
Dieser Fehler wurde in iOS 12.1 behoben. Ich wünsche Ihnen einen schönen Tag ~
Ich habe ein Problem mit dem Wertstatus von Array in der neu veröffentlichten iOS 12 Safari gefunden, z. B. Code wie folgt:
<!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>
Nach dem Aktualisieren der Seite wird der Wert des Arrays immer noch umgekehrt. Ist dies ein Fehler oder eine Funktion der neuen Safari?
Hier ist eine Demoseite. Versuchen Sie es mit iOS 12 Safari zu verwenden: https://abelyao.github.io/others/ios12-safari-bug.html
javascript
ios
safari
ios12
abelyao
quelle
quelle
Antworten:
Es ist definitiv ein Fehler! Und es ist ein sehr schwerwiegender Fehler.
Der Fehler ist auf die Optimierung von Array-Initialisierern zurückzuführen, bei denen alle Werte primitive Literale sind. Zum Beispiel mit der Funktion:
Alle zurückgegebenen Array-Verweise von Aufrufen an
buildArray()
werden mit demselben Speicher verknüpft, und bei einigen Methoden, z. B.toString()
werden die Ergebnisse zwischengespeichert. Um die Konsistenz zu gewährleisten, kopiert normalerweise jede veränderbare Operation auf solchen optimierten Arrays die Daten in einen separaten Speicherbereich und verknüpft sie damit. Dieses Muster wird als Copy-on-Write oder kurz CoW bezeichnet.Die
reverse()
Methode mutiert das Array und sollte daher eine Kopie beim Schreiben auslösen. Dies ist jedoch nicht derreverse()
Fall , da der ursprüngliche Implementierer (Keith Miller von Apple) den Fall verpasst hat, obwohl er viele Testfälle geschrieben hat.Dieser Fehler wurde Apple am 21. August gemeldet . Der Fix landete am 27. August im WebKit-Repository und wurde am 30. Oktober 2018 in Safari 12.0.1 und iOS 12.1 ausgeliefert.
quelle
Ich habe eine Bibliothek geschrieben, um den Fehler zu beheben. https://www.npmjs.com/package/array-reverse-polyfill
Dies ist der Code :
quelle
this.length = this.length
) Copy On Write auslöst, also die Speicheradresse des Arrays ändert und so das Verhalten von korrigiertreverse
.Dies ist ein Fehler im Webkit . Dies wurde zwar am Ende gelöst, aber noch nicht mit iOS GM Release ausgeliefert. Eine der Lösungen für dieses Problem:
quelle
Es scheint nicht zwischengespeichert zu werden, wenn sich die Anzahl der Elemente ändert.
So konnte ich das vermeiden.
quelle