eft*_*eft 51 javascript cross-browser
请考虑以下代码:
for (var i=0;i<3;i++){
var num = i + 0.50;
var output = num + " " + Math.round(num) + " " + num.toFixed(0);
alert(output);
}
Run Code Online (Sandbox Code Playgroud)
在Opera 9.63中我得到:
0.5 1 0
1.5 2 2
2.5 3 2
在FF 3.03我得到:
0.5 1 1
1.5 2 2
2.5 3 3
在IE 7中我得到:
0.5 1 0
1.5 2 2
2.5 3 3
注意粗体结果.为什么会出现这种不一致的情况?这是否意味着toFixed(0)应该避免?将数字舍入到最接近的整数的正确方法是什么?
tj1*_*111 34
编辑:要回答您的编辑,请使用Math.round.Number如果您更喜欢这种语法,您还可以对对象进行原型设计以使其进行出价.
Number.prototype.round = function() {
return Math.round(this);
}
var num = 3.5;
alert(num.round())
Run Code Online (Sandbox Code Playgroud)
我从来没有使用Number.toFixed()之前(主要是因为大多数JS库提供了一个toInt()方法),但你的结果来看,我会说这将是更一致的使用Math方法(round,floor,ceil),那么toFixed如果跨浏览器的一致性是你在找什么.
som*_*ome 12
我认为FF正在使用toFixed做正确的事情,因为下面的第10步说"如果有两个这样的n,请选择更大的n."
正如Grant Wagner所说:使用Math.ceil(x)或Math.floor(x)代替x.toFixed().
以下所有内容均来自ECMAScript语言规范:
15.7.4.5
Number.prototype.toFixed (fractionDigits)返回一个字符串,其中包含以定点表示法表示的
fractionDigits数字和小数点后的数字.如果fractionDigits未定义,0则假设.具体而言,执行以下步骤:
- 我们
f是ToInteger(fractionDigits).(如果fractionDigits未定义,则此步骤生成值0).- 如果
f < 0或f > 20,抛出RangeError异常.- 设
x这个数值.- 如果
x是NaN,则返回字符串"NaN".- 让我们
s成为空字符串.- 如果
x ? 0,请转到步骤9.- 我们是
"-".- 我们
x = –x.- 如果
x ? 10^21,让我们m = ToString(x)去第20步.- 让
n是一个整数,其确切的数学值n ÷ 10^f – x是接近零越好.如果有两个这样n,选择较大的n.- 如果
n = 0,让我们m成为字符串"0".否则,m设为由十进制表示的数字组成的字符串n(按顺序,没有前导零).- 如果
f = 0,请转到步骤20.- 让我们
k在字符数m.- 如果
k > f,请转到步骤18.- 我们
z是由字符串f+1–k的字符的出现'0'.- 我们
m是字符串的串联z和m.- 我们
k = f + 1.- 让我们
a成为第一个k–f角色m,让b剩下的f角色成为m.- 让
m是三个字符串的串联a,"."和b.- 返回字符串的连接
s和m.该方法的
length属性toFixed是1.如果
toFixed使用多个参数调用该方法,则行为未定义(请参阅第15节).允许实现扩展小于或大于的
toFixed值的行为.在这种情况下 ,不一定会抛出这样的值.fractionDigits020toFixedRangeError注意输出
toFixed可能比toString某些值更精确,因为toString只打印足够的有效数字以区分数字和相邻数字值.例如,(1000000000000000128).toString()返回"1000000000000000100"时(1000000000000000128).toFixed(0)返回"1000000000000000128".
Noy*_*oyo 11
解决您的两个原始问题:
这里的问题在于误解这些应该总是给出相同的结果.事实上,它们受不同规则的约束.例如,查看负数.由于Math.round采用"圆的一半了"作为规则,你会看到,Math.round(-1.5)计算结果为-1,即使Math.round(1.5)计算结果为2.
Number.prototype.toFixed另一方面,根据规范的第6步,使用基本上相当于"从零开始的一半"的规则,基本上将负数视为正数,然后在负数上添加负数.结束.因此,并且是所有符合规范的浏览器中的真实陈述.请注意,这些值是字符串,而不是数字.进一步,无论注意和是(数量),由于运算符优先级.(-1.5).toFixed(0) === "-2"(1.5).toFixed(0) === "2"-1.5.toFixed(0)-(1.5).toFixed(0)=== -2
大多数现代浏览器 - 或者至少是你在撰写本文时可能会支持的 浏览器除了IE之外 -都应该正确实现规范.(根据Renee的评论,toFixed你在Opera中指出的问题已得到解决,大概是因为他们开始使用与Chrome相同的JS引擎.)仍然值得重申的是,即使规范在所有浏览器中一致地实现,行为定义也是如此在规范中,特别是对于toFixed舍入,对于那些期望真正的数学准确性的"凡人"JS开发人员来说仍然有点不直观 - 请参阅Javascript toFixed Not Rounding并且这个"按预期工作"的错误已经在V8 JS引擎上提交了示例.
简而言之,这是两个不同的函数,具有两种不同的返回类型和两组不同的舍入规则.
正如其他人所建议的那样,我还想说"使用适合您特定用例的任何函数"(特别注意注意特殊性toFixed,尤其是IE的错误实现).我个人更倾向于推荐一些明确的组合 编辑: ...但是,在回过头来阅读你的澄清之后,你的用例(四舍五入到一个整数)肯定需要一个恰当命名的Math.round/ceil/floor,再次,正如其他人所提到的那样.Math.round函数.
toFixed()返回一个字符串值.来自Javascript:The Definitive Guide
将数字转换为包含小数位后指定位数的字符串.
Math.round()返回一个整数.
显然,toFixed()似乎更多用于赚钱,例如,
'$'+ 12.34253.toFixed(2)='$ 12.34'
很遗憾toFixed()似乎没有正确圆!
| 归档时间: |
|
| 查看次数: |
66809 次 |
| 最近记录: |