代码之家  ›  专栏  ›  技术社区  ›  Derek Adair

奇异的javascript算术行为(是的…应该是这样)

  •  4
  • Derek Adair  · 技术社区  · 15 年前

    好的,我写了一小段代码来获取昨天的ISO日期格式值。

    代码:

    var dateString = new Date();
    
    var yesterday = dateString.getFullYear();
    
        yesterday += "-"+dateString.getMonth()+1;
    
        yesterday += "-"+dateString.getDate()-1;
    

    上述代码输出2009-111-23。显然,它没有将datestring.getmonth()视为一个intiger并将1附加到它的末尾。

    将“—”+放在datestring.getdate()前面是否将getdate()强制转换为字符串?

    这项工作得到了预期的结果。

    var dateString = new Date();
    
    var yesterday = dateString.getFullYear() + "-";
    
        yesterday += dateString.getMonth()+1+ "-";
    
        yesterday += dateString.getDate()-1;
    //yesterday = 2009-12-22
    

    虽然我不太喜欢它的样子…不管怎样,没什么大不了的。

    有人能给我解释一下为什么javascript的行为是这样的吗?为什么会发生这种情况,有什么解释吗?

    10 回复  |  直到 15 年前
        1
  •  13
  •   Eugene Yokota    15 年前

    这是关于 associativity .+运算符是左相关的,因此

    "-"+dateString.getMonth() + 1
    

    一样

    ("-"+dateString.getMonth()) + 1
    

    在要首先计算的表达式周围加上括号:

    "-" + (dateString.getMonth() + 1)
    
        2
  •  3
  •   Matt Ball    15 年前

    获取表示“昨天”的日期值的正确方法是:

    var today = new Date();
    var yesterday = new Date(today.getTime() - (1000*60*60*24));
    

    从那里你可以得到你感兴趣的价值,比如 yesterday.getDate()

        3
  •  2
  •   Kieveli    15 年前

    它不起作用。在任何一个月的第一天尝试一下,你就会得到和昨天一样的“2009-12-0”报告。

    尝试如下操作:

    var mydate = new Date();
    mydate.setDate(mydate.getDate()-1);
    document.write(mydate.getFullYear() + "-" + (mydate.getMonth()+1) + "-" + mydate.getDate() );
    
        4
  •  1
  •   dball917    15 年前

    简而言之,javascript是弱类型的。这意味着直到运行时它才确定var是文本还是数字。因此,操作顺序很重要。看起来其他的海报都提到了关联性。

    记住,javascript是一种功能性语言,而不是面向对象的语言,因此没有您所知道的强制转换(尽管我认为可能有一些实用功能强制javascript将某些内容视为数字-我无法从头开始记起)。

        5
  •  0
  •   Kaleb Brasee    15 年前

    对, "-" + dateString.getMonth() 强制转换为字符串,因为其中一个参数是字符串。所以当你添加1时,它只是被附加到字符串中。这并不奇怪——这就是每种动态类型语言的工作原理。

    使用括号应该有效:

        yesterday += "-"+(dateString.getMonth()+1);
    
        yesterday += "-"+(dateString.getDate()-1);
    
        6
  •  0
  •   Mez    15 年前
    var dateString = new Date();
    
    var yesterday = dateString.getFullYear();
    
        yesterday += "-"+String(parseInt(dateString.getMonth())+1);
    
        yesterday += "-"+String(parseInt(dateString.getDate())-1);
    
        7
  •  0
  •   delfuego    15 年前

    您已经正确地理解了它——javascript首先对赋值的右侧进行评估,看到“-”字符,并提交将其他所有内容强制转换为字符串值。

    在第一个代码示例中,可以通过使用括号来防止过早的强制转换来获得所需的内容,如:

    var dateString = new Date();
    var yesterday = dateString.getFullYear();
    yesterday += "-" + (dateString.getMonth() + 1);
    yesterday += "-" + (dateString.getDate() - 1);
    

    当然,你仍然会有一个问题,你会报告一个月中的几天是零。-- getDate() 不是零索引。:)

        8
  •  0
  •   Phil H    15 年前

    正如基维利所提到的,这个月的第一天是行不通的。相反,从epoch开始计算基本的毫秒数,然后减去一天的值:

    var dateobj = new Date();
    var yesterdayms = dateobj.valueOf() - (24*60*60*1000);
    var yesterdayobj = new Date(yesterdayms);
    var yesterdaydatestring = yesterdayobj.getFullYear() + "-"
                            + (yesterdayobj.getMonth()+1) + "-"
                            + yesterdayobj.getDate();
    
        9
  •  0
  •   graphicdivine    15 年前

    试试这个:

    <script type="text/javascript">
    var d = new Date();
    document.writeln ("Today: " + d + "<br/>Yesterday:");
    d.setDate(d.getDate()-1);
    document.writeln (d);
    </script>
    

    编辑

    或者这个:

    <script type="text/javascript">
    var d = new Date();
    document.writeln ("Today: " +  (d.getDate()+1) + "-" + (d.getMonth()+1) + "-" + d.getFullYear() );
    d.setDate(d.getDate()-1);
    document.writeln ("<br/>Yesterday: " +  (d.getDate()+1) + "-" + (d.getMonth()+1) + "-" + d.getFullYear() );
    </script>
    
        10
  •  0
  •   kennebec    15 年前

    更直接的方法是获取昨天的日期方法,而不是从今天的日期中减去值。

    var d = new Date();
    d.setDate(d.getDate()-1); //yesterday
    var isodatestring= [d.getUTCFullYear(), 
    d.getUTCMonth(),d.getUTCDate()].join('-');