Mise à jour au 31/10/2018
Ce bug a été corrigé dans iOS 12.1, passez une bonne journée ~
J'ai trouvé un problème avec l'état de la valeur d'Array dans le nouveau iOS 12 Safari, par exemple, du code comme celui-ci:
<!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>
Après avoir actualisé la page, la valeur du tableau est toujours inversée. Est-ce un bug ou une fonctionnalité du nouveau Safari?
Voici une page de démonstration. Essayez de l'utiliser avec iOS 12 Safari: https://abelyao.github.io/others/ios12-safari-bug.html
javascript
ios
safari
ios12
abelyao
la source
la source
Réponses:
C'est définitivement un BUG! Et c'est un bug très grave.
Le bogue est dû à l'optimisation des initialiseurs de tableau dans lesquels toutes les valeurs sont des littéraux primitifs. Par exemple, étant donné la fonction:
Toutes les références de tableau renvoyées depuis les appels à
buildArray()
seront liées à la même mémoire, et certaines méthodes telles quetoString()
verront leurs résultats mis en cache. Normalement, pour préserver la cohérence, toute opération modifiable sur de tels tableaux optimisés copiera les données dans un espace mémoire séparé et y sera liée; ce modèle est appelé copie sur écriture , ou CoW pour faire court.La
reverse()
méthode mute le tableau, elle doit donc déclencher une copie sur écriture. Mais ce n'est pas le cas, car l'implémenteur d'origine (Keith Miller d'Apple) a raté lereverse()
cas, même s'il avait écrit de nombreux tests.Ce bogue a été signalé à Apple le 21 août. Le correctif a atterri dans le référentiel WebKit le 27 août et a été livré dans Safari 12.0.1 et iOS 12.1 le 30 octobre 2018.
la source
J'ai écrit une lib pour corriger le bug. https://www.npmjs.com/package/array-reverse-polyfill
Voici le code :
la source
this.length = this.length
) déclenchera la copie lors de l'écriture, donc changera l'adresse mémoire du tableau, et corrigera ainsi le comportement dereverse
.Il s'agit d'un bug dans le webkit . Bien que cela ait été résolu à la fin, mais pas encore livré avec la version iOS de GM. Une des solutions à ce problème:
la source
Il ne semble pas être mis en cache si le nombre d'éléments change.
J'ai pu éviter ça comme ça.
la source