abe*_*yao 433 javascript safari ios ios12
更新于2018.10.31
这个bug已经在iOS 12.1中得到修复,祝你有个美好的一天〜
我在新发布的iOS 12 Safari中发现了Array的值状态问题,例如,代码如下:
<!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>
Run Code Online (Sandbox Code Playgroud)
刷新页面后,数组的值仍然相反.这是新Safari的错误还是功能?
这是一个演示页面.尝试在iOS 12 Safari中使用它:https: //abelyao.github.io/others/ios12-safari-bug.html
hax*_*hax 272
这肯定是一个BUG!这是一个非常严重的错误.
该错误是由于数组初始值设定项的优化,其中所有值都是原始文字.例如,给定功能:
function buildArray() {
return [1, null, 'x'];
}
Run Code Online (Sandbox Code Playgroud)
从调用到所有返回的数组引用buildArray()将链接到相同的内存,并且某些方法(例如toString()将缓存其结果).通常,为了保持一致性,对这种优化数组的任何可变操作都会将数据复制到一个单独的存储空间并链接到它; 这种模式称为写时复制,或简称为CoW.
该reverse()方法会改变数组,因此它应该触发写时复制.但事实并非如此,因为最初的实施者(Apple的Keith Miller)错过了这个reverse()案子,尽管他写了很多测试用例.
该错误于8月21日向Apple报告.该修复程序于8月27日登陆WebKit存储库,并于2018年10月30日在Safari 12.0.1和iOS 12.1中发布.
Edi*_*Fan 75
我写了一个lib来修复bug. 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);
}
})();Run Code Online (Sandbox Code Playgroud)
jsi*_*ist 14
这是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;
}
}
})();
Run Code Online (Sandbox Code Playgroud)
小智 6
如果元素的数量发生变化,似乎不会被缓存.
我能够像这样避免这种情况.
<!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];
arr.push('');
arr.pop();
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>Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
78720 次 |
| 最近记录: |