Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

array.reverse bug su iOS 12. Safari is the new IE?

In Safari per iOS 12 il metodo reverse dell'oggetto Array non si comporta come ci si potrebbe aspettare.
array.reverse bug su iOS 12. Safari is the new IE?
In Safari per iOS 12 il metodo reverse dell'oggetto Array non si comporta come ci si potrebbe aspettare.
Link copiato negli appunti

Le nuove versioni dei browser, dei sistemi operativi o semplicemente degli aggiornamenti di un software portano spesso con loro dei bug e dei difetti che vanno individuati tempestivamente prima che le cose possano farsi problematiche. Questo è il caso di Safari su iOS versione 12, dove il metodo reverse dell'oggetto Array non si comporta come ci si potrebbe aspettare.

Quello postato dall'utente abelyao su Stack Overflow descrive infatti un bug molto subdolo, che si palesa utilizzando il metodo Array.prototype.reverse in un contesto come il seguente:

<!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>

Dopo che si effettua il refresh sulla pagina infatti, il valore dell'array rimane invertito. In questa pagina di demo è possibile testare quanto accade, ovviamente utilizzando Safari su iOS. L'errore è stato ufficializzato su Bugs.webkit.org.

Esso potrebbe essere provocato dalla procedura di ottimizzazione degli inizializzatori degli array, in cui tutti i valori sono valori primitivi. Come giustamente sottolineato dall'utente hax, per esempio, il codice () => [1, null, 'x'] restituisce dei riferimenti che linkano alla stessa locazione di memoria. Normalmente, le operazioni di modifica sugli array restituiti copiano i dati in uno spazio di memoria apposito e separato, collegandosi ad esso (copy on write). Il metodo reverse invece, presenta un bug in questa fase.

Ovviamente, in attesa di una risoluzione ufficiale, esistono già svariate soluzioni applicabili sull'inconveniente, come questo pacchetto postato su npm:

(function() {
  function buggy() {
    var a = [1, 2];
    return String(a) === String(a.reverse());
  }
  if(!buggy()) return;
  var r = Array.prototype.reverse;
  Array.prototype.reverse = function reverse() {
    if (Array.isArray(this)) this.length = this.length;
    return r.call(this);
  }
})();
O anche attraverso il seguente snippet:
(function() {
  function getReverseStr() {
    return [1, 2].reverse();
  }
  var n1 = getReverseStr()[0];
  var n2 = getReverseStr()[0];
  // check if there is an issue
  if(n1 != n2) {
    var origReverseFunction = Array.prototype.reverse;
    Array.prototype.reverse = function() {
      var newArr = this.slice();
      // use original reverse function so that edge cases are taken care of
      origReverseFunction.apply(newArr, arguments);
      var that = this;
      // copy reversed array
      newArr.forEach(function(value, index) {
        that[index] = value;
      });
      return this;
    }
  }
})();

Le operazioni con gli array sono di fondamentale importanza, e un bug su funzionalità native è da considerarsi grave allo stato attuale delle cose. Per questo motivo, tra alcuni sviluppatori, è iniziata a circolare la dicitura "Safari is the new IE"...

Ti consigliamo anche