배열 상태에 캐시됩니다 iOS12 습니다. 그것은 버그 또는 기능이?

업데이트 2018.10.31

이 버그가 수정되었습니다 iOS12.1,좋은 일~

내가 찾은 문제가 Array's 값은 상태에서 새롭게 출시된 iOS 12 사파리,예를 들어,다음과 같이 코드:

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

후에 페이지를 새로 고침,배열's 값은 여전히 반대입니다. 이것이 버그 또는 기능의 새로운 사파리?


여기에는 데모 페이지입니다. 이것을 사용하려고 시도와 함께 iOS12Safari: https://abelyao.github.io/others/ios12-safari-bug.html

질문에 대한 의견 (3)

It's 확실히는 독특한 기회를 제공합니다. 그's 는 아주 심각한다.

버그로 인해 최적화의 배열을 이니셜라이저는 모든 값은 원시적인 리터럴이 있습니다. 예를 들어,주어진 기능:

function buildArray() {
    return [1, null, 'x'];
}

모든 반환되는 배열을 참조에서 호출하여buildArray()를 최대한 활용할 수 있습니다 같은 메모리며,일부는 같은 방법toString()그들의 결과 캐시됩니다. 일반적으로 보존하기 위해 일관성,변경 가능한 모든 운영에 이러한 최적화된 배열로 복사합 데이터를 별도의 메모리 공간에 대한 링크를 이 패턴라[본](https://en.wikipedia.org/wiki/Copy-on-write 다),또는 소 짧습니다.

역()에서 변이의 배열을,그래서 그것을 트리거 복사기/쓰기가 가능합니다. 하지만 그't 기 때문에,원래 구현자(Keith 밀러의 애플)을 놓쳤역()의 경우에도,그가 기록했다 많은 testcases.

이 버그했다보고 애플on August21. Fix에 도착 웹 저장소on August27 배송에서 사파리 12.0.1 와 아이폰 os12.1on October30,2018.

해설 (4)

썼 lib 해결하는 버그입니다. https://www.npmjs.com/package/array-reverse-polyfill

이 코드:

(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);
  }
})();
해설 (2)

이것이 버그에서webkit. 하지만 이는 해결되었기에 그들의 끝나지만 아직 출 iOS GM 릴리스입니다. 중 하나 이 문제에 대한 해결책:

(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;
    }
  }
})();
해설 (0)

그것은 보인다하지 않는 경우 캐시되는 요소의 수를 변경합니다.
할 수 있었 이를 방지하기 위해 다음과 같다.




    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
    iOS 12 Safari bugs
    <script type="text/javascript">
    window.addEventListener("load", function ()
    {
        let arr = [1, 2, 3, 4, 5];
        arr.push('');
        arr.pop();
        alert(arr.join());

        document.querySelector("button").addEventListener("click", function ()
        {
            arr.reverse();
        });
    });
    </script>


    Array.reverse()
    <p style="color:red;">test: click button and refresh page, code:</p>

해설 (0)