iOS 12 safari 的 JS 引擎 reverse 现惊天 bug,或波及整个互联网

Posted justjavac

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了iOS 12 safari 的 JS 引擎 reverse 现惊天 bug,或波及整个互联网相关的知识,希望对你有一定的参考价值。

虽然 ios 12 的发布,很多人都升级了最新版,感觉确实快了不少。

但是昨天有人在 stackoverflow 发现了一个问题:

 
   
   
 
  1. let arr = [1, 2, 3, 4, 5];

  2. alert(arr.join());

  3. document.querySelector("button").addEventListener("click", function (){

  4.  arr.reverse();

  5. });

使用 reverse 函数将一个数组翻转,但是当重新刷新页面后,原数组依然是翻转的。不知道是 Safari 的 bug 还是 feature。

随后前端元老贺师俊(@johnhax)给出了一个可能的原因:

iOS 12 safari 的 JS 引擎 reverse() 惊天大 bug 之原因分析:Safari 对所有值是 primitive literal 的 array initializer 做了优化,同一个 initializer 产生的数组在内存里永远指向一份, reverse() 之后,所有从这个 initializer 得到的数组也都倒序了。


另一方面,其 toString() 的结果是预先计算缓存的,所以 toString() 结果并不会修改。按正常优化来说,如果某个这样的 array 执行了任何修改操作,应该复制到一份独立内存去。这是所谓 copy-on-write 的策略。但不幸的, reverse() 方法没有触发 CoW。


另一方面,所有不修改 array 的方法应该不触发 CoW。我实测下来,甚至 copyWithin 和 fill 这样的方法,如果 start/end 相同使得实际上并没有修改效果,也不会触发 CoW。


但是神奇的是 slice() 会触发 CoW。所以我猜有可能某个苹果的临时工把 reverseslice 的方法索引搞颠倒了。

昨天晚上明非(@fanmingfei)同学通宵写了一个 npm 包来解决这个问题 https://github.com/fanmingfei/array-reverse-ios12

并于凌晨 4 点将此包发布到了 npm,睡了 2 个小时的他今天又继续修复了几处 bug。

CDN 使用:

 
   
   
 
  1. <script src="//g.alicdn.com/mtb/fix-ios12-array/1.0.8/index.js"></script>

NPM 使用:

 
   
   
 
  1. import 'array-reverse-polyfill'

希望苹果早日修复此 bug。

最后,附一张贺老给这个库做的 logo。


以上是关于iOS 12 safari 的 JS 引擎 reverse 现惊天 bug,或波及整个互联网的主要内容,如果未能解决你的问题,请参考以下文章

引擎动态Cocos2d-JS将默认开启iOS 8 WebGL完美支持

Mac如何将Safari设置为默认搜索引擎?

iOS11今凌晨推送 360搜索正式接入Safari

移动 safari (iOS) 中的 javascript 不会下载日历邀请

360搜索正式接入iOS 11开发者Beta版Safari

如何从磁盘加载的 JS 在 Mobile Safari 中打开数据库