Atualizar em 2018.10.31
Este bug foi corrigido no iOS 12.1, tenha um bom dia ~
Encontrei um problema com o estado do valor da matriz no recém-lançado iOS 12 Safari, por exemplo, código como este:
<!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>
Após atualizar a página, o valor da matriz ainda é revertido. Isso é um bug ou um recurso do novo Safari?
Aqui está uma página de demonstração. Tente usá-lo com o iOS 12 Safari: https://abelyao.github.io/others/ios12-safari-bug.html
javascript
ios
safari
ios12
abelyao
fonte
fonte
Respostas:
É definitivamente um ERRO! E é um bug muito sério.
O erro ocorre devido à otimização dos inicializadores de matriz, nos quais todos os valores são literais primitivos. Por exemplo, dada a função:
Todas as referências de matriz retornadas de chamadas para
buildArray()
serão vinculadas à mesma memória e alguns métodos, comotoString()
terão seus resultados em cache. Normalmente, para preservar a consistência, qualquer operação mutável nessas matrizes otimizadas copiará os dados para um espaço de memória separado e vinculará a ele; esse padrão é chamado de cópia na gravação ou CoW, para abreviar.O
reverse()
método modifica a matriz e, portanto, deve acionar uma cópia na gravação. Mas não, porque o implementador original (Keith Miller, da Apple), perdeu oreverse()
caso, apesar de ter escrito muitos casos de teste.Esse bug foi relatado à Apple em 21 de agosto. A correção foi lançada no repositório WebKit em 27 de agosto e enviada no Safari 12.0.1 e iOS 12.1 em 30 de outubro de 2018.
fonte
Eu escrevi uma lib para corrigir o bug. https://www.npmjs.com/package/array-reverse-polyfill
Este é o código :
fonte
this.length = this.length
) acionará Copy On Write, alterará o endereço de memória da matriz e, portanto, corrigirá o comportamento dereverse
.Este é um erro no webkit . Embora isso tenha sido resolvido no final, mas ainda não tenha sido lançado com o iOS GM release. Uma das soluções para esse problema:
fonte
Parece não ser armazenado em cache se o número de elementos for alterado.
Eu era capaz de evitar isso assim.
fonte