跳至內容
Astera Technology

數字欄空白,不應自動變成零

數字欄的原文字、valueAsNumber 和 Number,要分開讀。

下載完整個案資料及參考答案 ↓

先看這個固定例子

程式依次設定空字串、0、2.5。欄位設 readonly,讓示範輸入固定;程式仍可改它的 value。

完整頁面內容與固定程式
<style>html{font-size:16px}body{margin:12px;font:1rem/1.5 system-ui,sans-serif;color:#17332d;background:#fff}p{overflow-wrap:anywhere}output{display:block;margin-block:12px;overflow-wrap:anywhere;white-space:pre-wrap}button,input{font:inherit;max-width:100%;box-sizing:border-box}button{margin:4px;padding:8px}label{display:block;margin-block:8px}button:focus-visible,input:focus-visible{outline:3px solid #23715d;outline-offset:2px}ul{padding-inline-start:24px}li{overflow-wrap:anywhere}.highlight{border:2px solid green}</style>
<label for="size">示範數值</label><input id="size" type="number" readonly><output id="result"></output>
<script>const input=document.querySelector('#size');const states=[];for(const value of ['', '0', '2.5']){input.value=value;states.push({value:input.value,asNumber:Number.isNaN(input.valueAsNumber)?'NaN':input.valueAsNumber,numberCoercion:Number(input.value)});}const result=states;
document.querySelector('#result').textContent=JSON.stringify(result);
console.log(JSON.stringify(result));
</script>
確實的 console 輸出
[{"value":"","asNumber":"NaN","numberCoercion":0},{"value":"0","asNumber":0,"numberCoercion":0},{"value":"2.5","asNumber":2.5,"numberCoercion":2.5}]
輸入與原生結果
核對項目所給輸入或動作結果
空白value: ""valueAsNumber: NaN; Number: 0
明確零value: "0"0 / 0
小數value: "2.5"2.5 / 2.5

原生機制怎樣處理

value 是字串。空白數字欄未能表示數字,valueAsNumber 得到 NaN;Number("") 卻得到零。輸出明確寫 NaN,不把它藏成 null。這裡只比較原生 API,不代替本地化數字解析或業務預設規則。

比較另一寫法

只把 value 交給 Number,空白與明確零都變零;事後比較數字,找不回哪一項原本未填。

另開的反例原始碼
<style>html{font-size:16px}body{margin:12px;font:1rem/1.5 system-ui,sans-serif;color:#17332d;background:#fff}p{overflow-wrap:anywhere}output{display:block;margin-block:12px;overflow-wrap:anywhere;white-space:pre-wrap}button,input{font:inherit;max-width:100%;box-sizing:border-box}button{margin:4px;padding:8px}label{display:block;margin-block:8px}button:focus-visible,input:focus-visible{outline:3px solid #23715d;outline-offset:2px}ul{padding-inline-start:24px}li{overflow-wrap:anywhere}.highlight{border:2px solid green}</style>
<label for="size">示範數值</label><input id="size" type="number" readonly><output id="result"></output>
<script>const input=document.querySelector('#size');input.value='';const blank=Number(input.value);input.value='0';const zero=Number(input.value);const result={blank,zero,same:blank===zero};
document.querySelector('#result').textContent=JSON.stringify(result);
console.log(JSON.stringify(result));
</script>
反例輸出
{"blank":0,"zero":0,"same":true}

試清邊界

把固定文字 "not-a-number" 賦給原生數字欄,value 最後留下甚麼?

查看參考答案

原生 value setter 把它清成空字串,valueAsNumber 是 NaN。要查真正 input;只執行 Number("not-a-number") 不能證明這個清理行為。

另開的邊界原始碼
<style>html{font-size:16px}body{margin:12px;font:1rem/1.5 system-ui,sans-serif;color:#17332d;background:#fff}p{overflow-wrap:anywhere}output{display:block;margin-block:12px;overflow-wrap:anywhere;white-space:pre-wrap}button,input{font:inherit;max-width:100%;box-sizing:border-box}button{margin:4px;padding:8px}label{display:block;margin-block:8px}button:focus-visible,input:focus-visible{outline:3px solid #23715d;outline-offset:2px}ul{padding-inline-start:24px}li{overflow-wrap:anywhere}.highlight{border:2px solid green}</style>
<label for="size">示範數值</label><input id="size" type="number" readonly><output id="result"></output>
<script>const input=document.querySelector('#size');input.value='not-a-number';const result={value:input.value,asNumber:Number.isNaN(input.valueAsNumber)?'NaN':input.valueAsNumber};
document.querySelector('#result').textContent=JSON.stringify(result);
console.log(JSON.stringify(result));
</script>
邊界輸出
{"value":"","asNumber":"NaN"}

原始例子檔案