当天的javascript-being-dumb体验

时间:2013-03-27 00:04:47

标签: javascript jquery

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

$(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);
});

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

  

未捕获的TypeError:无法调用未定义的方法'toString'

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

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

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

只是想分享我当时的JavaScript-dumb体验,并希望有人可以详细说明为什么会抛出这个错误,即使代码运行完美。

4 个答案:

答案 0 :(得分:1)

问题最有可能与:

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

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

以下是重现错误的示例:http://jsfiddle.net/m3Kza/1/(请参阅控制台)

控制台:'未捕获的TypeError:无法调用未定义'

的方法'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类用于以日期为文本的元素,并且仅对这些元素使用,这样您就知道自己在选择什么。

答案 1 :(得分: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);

答案 2 :(得分: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>

答案 3 :(得分: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()中的块元素数量无关紧要。我的小提琴有多个diveach()中运行,而且效果很好。

Fiddle with it