1

人们会认为将 3 个字符的缩写转换为数字表示将是一件容易的事。JavaScript 说“不!”。

$(selector).each(function() {
    // convert month abbreviation to numerical representation
    var monthStr = $(this).text().match(/[^\/]*/)[0];
    var months = {
        JAN: 1,
        FEB: 2,
        MAR: 3,
        APR: 4,
        MAY: 5,
        JUN: 6,
        JUL: 7,
        AUG: 8,
        SEP: 9,
        OCT: 10,
        NOV: 11,
        DEC: 12
    };
    var month = months[monthStr].toString();
    var date = $(this).text().replace(monthStr, month);
    $(this).text(date);
});

即使代码有效且有效,我的控制台仍然出现以下错误:

未捕获的类型错误:无法调用未定义的方法“toString”

这绝对没有意义,因为选择器的文本被正确替换(至少根据眼睛)。

当我声明“monthStr”变量时,问题似乎就开始了。如果我将其设置为静态“MAR”作为示例并从“月”变量定义中删除“.toString()”,则不再发生错误。

此外,唯一保存代码的是已经提到的我的月份变量的“.toString()”转换。如果它不在那里,我最终会得到一个“未定义”的值。

只是想分享我当天的 JavaScript 愚蠢经历,并希望有人可以详细说明为什么会抛出这个错误,即使代码完美无缺。

4

4 回答 4

1

问题很可能与:

$(selector).each(function() { ... });

什么是选择器,选择了多少个 DOM 对象?很可能正在选择一个没有日期作为文本的 DOM 对象。

这是一个重现您的错误的示例:http: //jsfiddle.net/m3Kza/1/(参见控制台)

控制台:'未捕获的类型错误:无法调用未定义的方法'toString'

<p>MAR/26/2013</p>
<p>Hello world!</p>

$('p').each(function() {
    var month = $(this).text().match(/[^\/]*/)[0];

    var months = {
        MAR: 3
    };

    alert(months[month].toString());
});

这样做的原因是因为我们选择了两个<p>元素,并且只有一个元素具有日期作为文本。

如果我们将代码限制为将日期作为文本的 DOM 对象,它可以正常工作:http: //jsfiddle.net/m3Kza/

<p>MAR/26/2013</p>

var month = $('p').text().match(/[^\/]*/)[0];

var months = {
    MAR: 3
};

alert(months[month].toString());   

您应该将 CSS 类用于将日期作为文本的元素,并且仅用于这些元素,这样您就知道您在选择什么。

于 2013-03-27T00:46:58.223 回答
0

我对您的代码进行了一些细微的改进,并且没有收到任何错误:

<!doctype html>
<html lang="en">
    <head> 
        <meta charset="utf-8" />  
        <title>Test the script</title>
        <script type="text/javascript" src="jquery-1.9.0.js"></script>
        <script>
            $(document).ready(function(){
                $("div").each(function() {
                    // convert month abbreviation to numerical representation
                    var orgStr=$(this).text().trim().match(/[^\/]*/)[0];
                    var monthStr = orgStr.toUpperCase().substr(0,3);
                    console.log("monthStr is:", monthStr);
                    var months = {
                        JAN: 1,
                        FEB: 2,
                        MAR: 3,
                        APR: 4,
                        MAY: 5,
                        JUN: 6,
                        JUL: 7,
                        AUG: 8,
                        SEP: 9,
                        OCT: 10,
                        NOV: 11,
                        DEC: 12
                    };
                    if(months[monthStr]!==undefined){
                        var month = months[monthStr].toString();
                        var date = $(this).text().replace(orgStr, month);
                        $(this).text(date);
                    }
                }); 
            });
        </script>  

    </head>
    <body> 
        <div>JAN/22/2012</div>
        <div>
            JAN/22/2012</div>
        <div>nope/22/2012</div>
        <div>Feb/22/2012</div>
        <div>dec/22/2012</div>
        <div>jul/22/2012</div>
        <div>
            october/22/2012</div>
    </body>
</html>
于 2013-03-27T00:59:21.460 回答
0

利用trim

 var monthStr = $(this).text().match(/[^\/]*/)[0];
    monthStr = monthStr.trim();

    var months = {
            "JAN": 1,
            "FEB": 2,
            "MAR": 3,       
        };

        var month = months[monthStr].toString();
        alert(month);
于 2013-03-27T00:09:24.507 回答
0
  • 直接打电话trim()应该适合你:

var monthStr = $(this).text().match(/[^\/]*/)[0].trim();
  • 添加一个if/else块以确定月份的正确值:

if(monthStr !== undefined && monthStr.length === 3) {

实际上,如果您只是检查对象中的元素是否存在,则不需要此检查。

  • 然后检查是否months[monthStr]存在:

var month = (months[monthStr]) ? months[monthStr].toString() : monthStr

对于完整的代码

$("div").each(function() {
    // convert month abbreviation to numerical representation
    var el = $(this);
    var monthStr = el.text().match(/[^\/]*/)[0].trim();        
    var months = {
        JAN: 1,
        FEB: 2,
        MAR: 3,
        APR: 4,
        MAY: 5,
        JUN: 6,
        JUL: 7,
        AUG: 8,
        SEP: 9,
        OCT: 10,
        NOV: 11,
        DEC: 12
    };
    var month = (months[monthStr]) ? months[monthStr].toString() : monthStr;
    el.text(el.text().replace(monthStr, month));
});

块元素的数量each()无关紧要。我的小提琴有多个divs 通过 an 运行each(),它工作得很好。

摆弄它

于 2013-03-27T01:05:15.283 回答