为啥这个函数返回 NaN?
Posted
技术标签:
【中文标题】为啥这个函数返回 NaN?【英文标题】:Why is this function returning NaN?为什么这个函数返回 NaN? 【发布时间】:2016-03-21 10:49:06 【问题描述】:起初,这似乎与许多其他关于 javascript 中的 NaN 的问题相似,但我向您保证不是。
我有这段代码可以转换从文本框中获取值,并在单击表单中的按钮后将其转换为日期:
var dateString = $('#itemAcquiredTxt').val(); //Would have a value of '2013-12-15'
var dateAcquired = new Date(dateString); //Invalid Date ?
文本框 itemAcquiredTxt 的值为“2013-12-15”(YYYY-MM-DD 格式),取自数据库调用:
$('#itemAcquiredTxt').val(new Date(item.DateAcquired).toLocaleDateString());
创建新的 Date 对象后,它给了我“无效日期”。
好的...所以我想通过将年、月和日作为数字传递来制作 Date 对象 - 它的其他构造函数之一。
var year = Number(dateString.split("-")[0]); //Returns NaN
var month = Number(dateString.split("-")[1]); //Returns NaN
var day = Number(dateString.split("-")[2]); //Returns NaN
var dateAcquired = new Date(year, month - 1, day); //InvalidDate
我尝试用破折号分割日期文本框中的字符串,并使用 Number 和 parseInt 将字符串转换为数字 - 但两者都给了我一个 NaN。我仔细检查了字符串值,似乎没有错:分别在拆分项目上显示“2013”、“12”、“15”。
我对自己说...也许我的代码不好,并在 JSFiddle 上尝试过 https://jsfiddle.net/jrxg40js/ 但正如您所见,在文本中放置日期并按下按钮后,它就可以工作了!
这是相关的 html 代码
<table id="inputTable">
<tr>
<td><span><strong>Name:</strong></span></td>
<td><input id="itemNameTxt" type="text" value="" /></td>
</tr>
<tr>
<td><span><strong>Category:</strong></span></td>
<td>
<select id="categorySelect" ng-model="selectedCategory" ng-change="changeSubCategoryList(selectedCategory)" ng-options="cat as cat.CategoryName for cat in categoriesObj track by cat.CategoryID">
<option value="">---Please Select One---</option>
</select>
</td>
</tr>
<tr ng-show="hasSubCat">
<td><span><strong>Sub Category</strong></span></td>
<td>
<select id="subCategorySelect">
<option value="">---Please Select One---</option>
<option ng-repeat="sub in subCategoryObj" value="sub.SubCatID">sub.SubCatName</option>
</select>
</td>
</tr>
<tr>
<td><span><strong>Description:</strong></span></td>
<td><input id="itemDescriptionTxt" type="text" value="" /></td>
</tr>
<tr>
<td><span><strong>Serial Number:</strong></span></td>
<td><input id="itemSerialNumberTxt" type="text" value="" /></td>
</tr>
<tr>
<td><span><strong>Year:</strong></span></td>
<td><input id="itemYearTxt" type="text" value="" /></td>
</tr>
<tr>
<td><span><strong>Initial Cost:</strong></span></td>
<td><input id="itemValueTxt" type="text" value="" /></td>
</tr>
<tr>
<td><span><strong>Department:</strong></span></td>
<td>
<select id="departmentSelect">
<option value="">---Please Select One---</option>
<option ng-repeat="dep in departmentsObj" value="dep.RoleID">dep.RoleDescription</option>
</select>
</td>
</tr>
<tr>
<td><span><strong>Campus:</strong></span></td>
<td>
<select id="campusSelect" ng-model="selectedCampus" ng-change="changeBuildingList(selectedCampus)" ng-options="campus as campus.CampusDescription for campus in campusesObj track by campus.CampusID">
<option value="">---Please Select One---</option>
</select>
</td>
</tr>
<tr>
<td><span><strong>Building:</strong></span></td>
<td>
<select id="buildingSelect">
<option value=""> </option>
<option ng-repeat="building in buildingsObj" value="building.BuildingID">building.BuildingDescription</option>
</select>
</td>
</tr>
<tr>
<td><span><strong>Date Acquired:</strong></span></td>
<td><input id="itemAcquiredTxt" type="text" value="" /></td>
</tr>
<tr>
<td><span><strong>Notes:</strong></span></td>
<td>
<textarea id="noteTxt"></textarea>
</td>
</tr>
</table>
用于使用用户键入的新数据更新项目的相关 AngularJS 函数 - 当用户按下确认按钮时调用该函数:
$scope.editItem = function ()
var dateString = $('#itemAcquiredTxt').val();
dateAcquired = new Date(dateString);
var invItem =
ItemID: $('#itemID').val(),
ItemName: $('#itemNameTxt').val().trim(),
CategoryID: $('#categorySelect').find(":selected").val(),
SubCategoryID: $('#subCategorySelect').find(":selected").val(),
Description: $('#itemDescriptionTxt').val().trim(),
SerialNumber: $('#itemSerialNumberTxt').val().trim(),
Year: $('#itemYearTxt').val().trim(),
DateAcquired: dateAcquired,
Value: $('#itemValueTxt').val().trim(),
RoleID: $('#departmentSelect').find(":selected").val(),
Barcode: null,
Notes: $('#noteTxt').val().trim(),
Deleted: null,
AddedBy: null,
DateAdded: null,
ModifiedBy: null, //Added by server
DateModified: null,
DeletedBy: '',
DateDeleted: null,
CampusID: $('#campusSelect').find(":selected").val(),
BuildingID: $('#buildingSelect').find(":selected").val(),
RoomID: null
;
$http.put("api/inventory/", invItem).success(function (data, status, headers, config)
inventoryData.retrieveData(); //On success, refresh zeh data
).error(function (data, status, headers, config)
console.log(data);
);
$("#dialogForm").dialog("close");
为什么我的代码在我的工作环境(IE11 上的 Visual Studio 2015 调试)上返回 NaN,而 JSFiddle 等其他网站正在返回我所期望的内容?
【问题讨论】:
您有多大把握日期字符串确实是您认为的那样?在使用console.log()
进行约会或通过浏览器调试器检查之前,您是否使用过console.log()
将其转储到控制台?一定是事情并没有像你想象的那样发生。验证你的所有假设!
例如:您确定页面上只有一个<input>
具有该ID吗?
你能给我们看看相关的HTML代码吗?如果不知道 #itemAcquiredTxt
的样子,我们将无法为您提供帮助。
itemAcquiredTxt
是别的东西。
Visual Studio 2015 似乎是 Microsoft 的问题.. 但@Pointy 是正确的,看看您在浏览器和 Visual Studio 2015 中是否得到相同的console.log
结果
【参考方案1】:
解决了这个问题——我真的不知道它到底是什么。
问题仅在更新项目时发生,而不是在添加新项目时发生 - 所以它必须在我填充元素值时出现。
$('#itemAcquiredTxt').val(new Date(item.DateAcquired).toLocaleDateString());
执行console.log(item.DateAcquired)
返回字符串“2015-12-15T00:00:00”,.toLocaleDateString() 会将其转换为“2015-12-15”并解析为 Date 对象。
在尝试将其字符串转换为日期时,编辑该元素的值总是会导致 NaN/InvalidDate。
我的解决方案是……
$('#itemAcquiredTxt').val(item.DateAcquired.split('T')[0]);
根本不使用日期。 现在它起作用了。
【讨论】:
以上是关于为啥这个函数返回 NaN?的主要内容,如果未能解决你的问题,请参考以下文章