为什么这个函数返回 NaN?

7

一开始,这可能看起来像许多已经关于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");

为什么我的代码在我工作环境中(Visual Studio 2015调试IE11)返回NaN,而其他网站(如JSFiddle)返回我期望的结果?

6
你对日期字符串的准确性有多确定?在使用它生成日期或通过浏览器调试器进行检查之前,是否使用 console.log() 将其输出到控制台中了?一定有一些事情不是你想象中的那样。验证所有你的假设! - Pointy
非常确定。已经检查了浏览器调试器和控制台日志。 是的,只有一个具有该ID的输入框。 - Cuauhtemoc
1
你能给我们展示相关的 HTML 代码吗?如果不知道 #itemAcquiredTxt 是什么样子,我们将无法帮助你。 - Kayla
2
itemAcquiredTxt是另外一种东西。 - Jai
1
似乎是Visual Studio 2015的Microsoft问题...但@Pointy是正确的,请查看您在浏览器和Visual Studio 2015中是否获得相同的console.log结果。 - Jonathan Marzullo
显示剩余12条评论
1个回答

1

已解决问题 - 实际上我甚至不知道它是什么。

问题只在更新项目时发生,而不是在添加新项目时发生 - 因此它必须在我填充元素值时出现。

$('#itemAcquiredTxt').val(new Date(item.DateAcquired).toLocaleDateString());

执行console.log(item.DateAcquired)返回一个字符串 "2015-12-15T00:00:00",使用.toLocaleDateString()将其转换为 "2015-12-15" 并解析成一个日期对象。

编辑该元素的值时,尝试将其字符串转换为日期会始终导致NaN/InvalidDate。

我的解决方案是...

$('#itemAcquiredTxt').val(item.DateAcquired.split('T')[0]);

不使用日期。 现在它可以工作。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接