iOS 12 safari 的 JS 引擎 reverse 现惊天 bug,或波及整个互联网
Posted justjavac
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了iOS 12 safari 的 JS 引擎 reverse 现惊天 bug,或波及整个互联网相关的知识,希望对你有一定的参考价值。
虽然 ios 12 的发布,很多人都升级了最新版,感觉确实快了不少。
但是昨天有人在 stackoverflow 发现了一个问题:
let arr = [1, 2, 3, 4, 5];
alert(arr.join());
document.querySelector("button").addEventListener("click", function (){
arr.reverse();
});
使用 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。所以我猜有可能某个苹果的临时工把reverse
/slice
的方法索引搞颠倒了。
昨天晚上明非(@fanmingfei)同学通宵写了一个 npm 包来解决这个问题 https://github.com/fanmingfei/array-reverse-ios12
并于凌晨 4 点将此包发布到了 npm,睡了 2 个小时的他今天又继续修复了几处 bug。
CDN 使用:
<script src="//g.alicdn.com/mtb/fix-ios12-array/1.0.8/index.js"></script>
NPM 使用:
import 'array-reverse-polyfill'
希望苹果早日修复此 bug。
最后,附一张贺老给这个库做的 logo。
以上是关于iOS 12 safari 的 JS 引擎 reverse 现惊天 bug,或波及整个互联网的主要内容,如果未能解决你的问题,请参考以下文章
引擎动态Cocos2d-JS将默认开启iOS 8 WebGL完美支持