JavaScript - 数字数据与 NaN
我确信我违反了 javascript 的一些深刻的黑暗法则,但我并不是真正的 JS 开发人员,这让我发疯。在订单上调用此函数来逐行读取商品的数量和价格,然后提供小计、交货和总计。
问题出在第 10 行 - 它一直“忘记”整个变量数据是数字(浮点),因此返回大量 NaN。如何强制整个函数中的变量表现为数字而不是字符串?
编辑
这是根据迄今为止的反馈修改后的代码(谢谢!)。它仍然不起作用;)
<script type="text/javascript">
function subTotal(rows) {
var i, subTotal, lineTotal, orderShip, orderTotal;
for (i = 1; i <= rows; ++i) {
//Grab values from form
var quantity = parseFloat($('#quantity' + i).val());
var uPrice = parseFloat($('#uPrice' + i).val());
//Error checking
alert('quantity = ' + quantity +' and uPrice = ' + uPrice);
if (isNaN(quantity)) alert('quantity = NaN');
if (isNaN(uPrice)) alert('uPrice = NaN');
if ((quantity == '') || (uPrice == '')) {
} else {
lineTotal = quantity * uPrice;
alert('lineTotal = ' + lineTotal);
subTotal += lineTotal;
alert('subTotal = ' + subTotal);
}
//If we've maxed out the number of rows, then subTotal should be calculated - push back to form.
if (i == rows) {
$('#orderSubTotal').val(subTotal );
orderShip = subTotal * 0.25;
$('#orderShip').val(orderShip.toFixed(2));
orderTotal = subTotal + orderShip;
$('#orderTotal').val(orderTotal.toFixed(2));
}
}
}
</script>
<form>
<table>
<tr>
<td><input type="text" id="item1" name="item1" value="Some description" readonly="readonly" /></td>
<td><input type="text" id="quantity1" name="quantity1" value="25" onchange="javascript:subTotal('2')" /></td>
<td><input type="text" id="uPrice1" name="uPrice1" value="1.50" readonly="readonly" /></td>
</tr>
<tr>
<td><input type="text" id="item2" name="item2" value="Some description" readonly="readonly" /></td>
<td><input type="text" id="quantity2" name="quantity2" value="25" onchange="javascript:subTotal('2')" /></td>
<td><input type="text" id="uPrice2" name="uPrice2" value="2.75" readonly="readonly" /></td>
</tr>
<tr>
<td colspan="3">
SubTotal
<input type="text" id="orderSubTotal" name="orderSubTotal" readonly="readonly" style="text-align: right" value="0.00" />
<br />Shipping
<input type="text" id="orderShip" name="orderShip" readonly="readonly" style="text-align: right" value="0.00" />
<br />Total
<input type="text" id="orderTotal" name="orderTotal" readonly="readonly" style="text-align: right" value="0.00" />
</td>
</tr>
</table>
</form>
I'm sure I'm contravening some deep dark law of javascript, but I'm not really a JS developer and this is driving me mad. This function is called on an orderform to read the quantity and price of items, row by row, and then provide the subtotal, delivery and total.
The problem is with line 10 - it keeps "forgetting" that the variable data throughout is numeric (floating point) and so returns lots of NaN. How can I force the variables throughout this function to behave as numbers rather than strings?
EDIT
Here's the revised code based on feedback so far (thank you!). It's still not working ;)
<script type="text/javascript">
function subTotal(rows) {
var i, subTotal, lineTotal, orderShip, orderTotal;
for (i = 1; i <= rows; ++i) {
//Grab values from form
var quantity = parseFloat($('#quantity' + i).val());
var uPrice = parseFloat($('#uPrice' + i).val());
//Error checking
alert('quantity = ' + quantity +' and uPrice = ' + uPrice);
if (isNaN(quantity)) alert('quantity = NaN');
if (isNaN(uPrice)) alert('uPrice = NaN');
if ((quantity == '') || (uPrice == '')) {
} else {
lineTotal = quantity * uPrice;
alert('lineTotal = ' + lineTotal);
subTotal += lineTotal;
alert('subTotal = ' + subTotal);
}
//If we've maxed out the number of rows, then subTotal should be calculated - push back to form.
if (i == rows) {
$('#orderSubTotal').val(subTotal );
orderShip = subTotal * 0.25;
$('#orderShip').val(orderShip.toFixed(2));
orderTotal = subTotal + orderShip;
$('#orderTotal').val(orderTotal.toFixed(2));
}
}
}
</script>
<form>
<table>
<tr>
<td><input type="text" id="item1" name="item1" value="Some description" readonly="readonly" /></td>
<td><input type="text" id="quantity1" name="quantity1" value="25" onchange="javascript:subTotal('2')" /></td>
<td><input type="text" id="uPrice1" name="uPrice1" value="1.50" readonly="readonly" /></td>
</tr>
<tr>
<td><input type="text" id="item2" name="item2" value="Some description" readonly="readonly" /></td>
<td><input type="text" id="quantity2" name="quantity2" value="25" onchange="javascript:subTotal('2')" /></td>
<td><input type="text" id="uPrice2" name="uPrice2" value="2.75" readonly="readonly" /></td>
</tr>
<tr>
<td colspan="3">
SubTotal
<input type="text" id="orderSubTotal" name="orderSubTotal" readonly="readonly" style="text-align: right" value="0.00" />
<br />Shipping
<input type="text" id="orderShip" name="orderShip" readonly="readonly" style="text-align: right" value="0.00" />
<br />Total
<input type="text" id="orderTotal" name="orderTotal" readonly="readonly" style="text-align: right" value="0.00" />
</td>
</tr>
</table>
</form>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我认为真正问题出在您的循环中:您从
0
循环到行
包含。因此,如果您为rows
传入10
,则将循环 11 次,从0
开始,一直到(包括)10.
.我怀疑这才是你真正的问题。如果您没有quantity0
元素,或者(假设rows
为10
),则您没有quantity10
code> 元素,那么$("#quantity" + i).val()
将返回undefined
,转换时会转换为NaN
它(隐式或显式)。 (uPrice0
/uPrice10
也是如此。)当然,一旦有了NaN
,任何 数学运算使用它会导致NaN
。至于你关于如何确保它们不改变的问题,基本上,尽早将它们转换为数字。您当前正在使用
quantity
和uPrice
而不进行转换,这意味着它们最初是字符串。现在,JavaScript 可以非常智能地为您转换它们,但有时您想要明确地进行转换。另外:
x
从哪里来?您还没有显示任何可供使用的数据,而只是推测:
I think the real problem is in your loop: You're looping from
0
torows
inclusive. So if you pass in10
forrows
, you'll be looping 11 times, starting with0
and continuing through (including)10
. I suspect that's your real problem. If you don't have aquantity0
element, or (assumingrows
is10
) you don't have aquantity10
element, then$("#quantity" + i).val()
will returnundefined
, which converts toNaN
when you convert it (implicitly or explicitly). (And the same foruPrice0
/uPrice10
.) And of course, once you haveNaN
, any mathematical operation using it results inNaN
.In terms of your question about how to ensure they don't change, basically, convert them to numbers early. You're currently using
quantity
anduPrice
without converting them, which means initially they're strings. Now, JavaScript is pretty smart about converting them for you, but sometimes you want to be explicit.Separately: Where does
x
come from?You haven't shown any data to work with, but just speculatively:
问题在于,您在使用 parseFloat 之前对字段执行数学计算:
在获得值时执行解析,以使生活变得更轻松:
然后更改 subTotal = 行:
另一个可能的问题是,如果
$('#uPrice' + i).val()
的结果不是以可解析的浮点开头 — 如果它以货币符号,例如£
或$
—parseFloat
将始终为该字段返回NaN
。您可以使用$('#uPrice' + i).val().slice(1)
解决此问题。The problem is that you're performing a mathematical calculation on the fields before using
parseFloat
:Perform your parsing at the point you get the values to make life a little easier:
Then change the
subTotal =
line to this:Another possible issue is if the result of
$('#uPrice' + i).val()
doesn't start with a parseable float — if it starts with a currency symbol, e.g.£
or$
, for instance —parseFloat
will always returnNaN
for that field. You can work around it using$('#uPrice' + i).val().slice(1)
.进行一些错误检查:
您可能在某个时候遇到索引问题,从其中一个(不存在的字段)获取
NaN
,并将其添加到subTotal
这使得它立即成为NaN
。Do some error checking:
You're probably running into an index problem at some point, getting a
NaN
from one of the (non-existing fields), adding it tosubTotal
which makes it aNaN
instantly.您最好在进行任何数学运算之前转换该值。所以代码应该是:
You better convert the value before doing any mathematical operation. So the code should be: