经在此页面反复测试:https://layui.gitee.io/v2/demo/ 未发现负数问题
从截图来看,你并非是在当前官网文档页测试的例子,有可能是后端提供的数据本身没做好分页数控制。
这是在 Gitee 极其少见的能有如此认真和严谨的回复
该 BUG 确实存在。|
运算符在早期的目的是为了将任意类型的值化整,但对于位数太长的数字的确处理不妥。
下个版本修复。
因为Layui值得被认真对待
经测试官网文档确实有负数情况发生,说一下我的操作:
1、在文档首页右侧表格页跳转输入框中较大的数字值,例如2147483649
:
2、点击“确定”,输入框内数字变成负值,页码导航栏无对应选中页码。
6442450943
是大于2147483649
,但是这个值正确处理了。|
与0进行位运算,从图中可以看出2147483649
与0进行或运算之后变成了一个负数(见Watch中的变量e的值),而这个值就是最后渲染到页面输入框中的值:到这里,应该能够确定,就是这个|
运算符出现了问题,有些值在与0进行|
时,结果并不等于它本身,而是成为了一个负数值。|0
的操作从代码逻辑上来看是将字符串转换成为数字,那么使用Number()进行替换是一种解决方案。
但是问题依然存在,为什么有些很大的值,例如6442450943
代码依然能够正常处理,有些例如2147483649
不能呢?
探究|
运算符的秘密
从代码中可以看到,代码是用数字字符串与数字0进行按位或运算,那么自然逻辑(不涉及底层二进制计算逻辑)应该是:
在W3School的资料中得到了以下信息:
所以我们可以大概得出,出现负数的可能原因是:js在做位运算时会将数字转换为32位的二进制数,如果不够在前面补0至32为,如果超过则截断取后32位。
由此我们可以设计一个实验:
10000000000000000000000000000000
(二进制长度32位,十进制值:2147483647)与0进行|
运算,查看结果。100000000000000000000000000000000
(二进制长度33位,十进制值:4294967296)与0进行|
运算,查看结果。110000000000000000000000000000000
(二进制长度33位,十进制值:6442450944)与0进行|
运算,查看结果。0
(二进制长度1位,十进制值:0)与0进行|
运算,查看结果。实验结果:
从实验结果中我们可以看到1和3的结果是相同的,2和4的结果是相同的。所以我们可以认为,之前的猜测是正确的。
探究为何十进制数值6442450943
能正常运行
使用Number中的toString(2)
方法查看6442450943
的二进制数是101111111111111111111111111111111
(二进制长度33),按照上个实验得出的结论应该在位运算中等价与01111111111111111111111111111111
(二进制长度32),|0
的运算结果是2147483647
。
不对劲啊,页面上显示的不是2147483647啊,是在哪里做了处理吗?
继续追踪代码,最后找到在view方法中有一个逻辑:
可以看到,在这里使n.curr(原本应该是拿来存储当前页码,在此场景下为输入值与0|运算之后的值)与n.pages(服务器返回的最大页数)做了比较,如果n.curr大于n.pages,则将n.pages赋予n.curr,以此来保障当前页数永远小于等于最大页数。
所以问题出现了,当n.curr是负数的情况下,n.curr小于n.pages时满足的,因此不会执行修正代码,所以最后页面渲染出现了负数。
通过上面的分析及实验我得出了以下结论:
|
来进行数据类型转换,导致js进行了位运算,得出了错误的数值。使用Number()进行替换进行转换是一种可行的方案。此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。
刚刚发布的 v2.7.0
已优化该问题。
同时也特别点赞 @Breakpoint 在本帖中所展现的个人技术素养,虽然只是个小问题,但这种探索的过程和认真对待每一个技术细节的态度,非常令人值得学习。
登录 后才可以发表评论