2011-02-17 96 views
12

http://ejohn.org/files/pretty.js有人可以解释John Resig的pretty.js JavaScript是如何工作的吗?

// Takes an ISO time and returns a string representing how 
// long ago the date represents. 
function prettyDate(time){ 
    var date = new Date((time || "").replace(/-/g,"/").replace(/[TZ]/g," ")), 
     diff = (((new Date()).getTime() - date.getTime())/1000), 
     day_diff = Math.floor(diff/86400); 

    if (isNaN(day_diff) || day_diff < 0 || day_diff >= 31) 
     return; 

    return day_diff == 0 && (
      diff < 60 && "just now" || 
      diff < 120 && "1 minute ago" || 
      diff < 3600 && Math.floor(diff/60) + " minutes ago" || 
      diff < 7200 && "1 hour ago" || 
      diff < 86400 && Math.floor(diff/3600) + " hours ago") || 
     day_diff == 1 && "Yesterday" || 
     day_diff < 7 && day_diff + " days ago" || 
     day_diff < 31 && Math.ceil(day_diff/7) + " weeks ago"; 
} 

// If jQuery is included in the page, adds a jQuery plugin to handle it as well 
if (typeof jQuery != "undefined") 
    jQuery.fn.prettyDate = function(){ 
     return this.each(function(){ 
      var date = prettyDate(this.title); 
      if (date) 
       jQuery(this).text(date); 
     }); 
    }; 

究竟是如何prettyDate()方法返回一个字符串?这是另一个你能用JavaScript做的“奇怪”事情吗?还是我错过了一些东西?

编辑:我没有问他是如何返回一个值,我问他如何返回一个字符串。

return day_diff == 0 && (....)以我曾经使用的任何语言返回布尔值。

+0

呃,使用return语句?在它只是说回报是价值零的情况下? – 2011-02-17 04:13:16

+2

“`&&以我曾经使用过的任何语言返回一个布尔值” - 然后你还没有使用过很多语言。 ;-) – deceze 2011-02-17 04:18:40

+0

并非所有的东西都用真正的真值来检查“真”和“假”。 JavaScript使用“truthy”和“falsey”的值 – 2011-02-17 04:20:58

回答

9

它说在那里:return ...,然后进入基本上长的嵌套列表“内联ifs“。 ;-)

在JavaScript中,布尔运算符返回值一个操作数的,不只是truefalse。例如。 0 || 'foo'返回'foo'。该特性与操作员短路一起使用。 false && true将不会立即评估true方和返回false,因为整个表达式必须是false

27

在JavaScript:

  • a || b相当于a ? a : b
  • a && b相当于a ? b : a
  • 在布尔表达式中的任何非空字符串的值为true

有了这些知识,return语句的逻辑变得相当简单。

假设,例如,该day_diff = 5

然后,从上述步骤一步采取语句:

return day_diff == 0 && (
     diff < 60 && "just now" || 
     diff < 120 && "1 minute ago" || 
     diff < 3600 && Math.floor(diff/60) + " minutes ago" || 
     diff < 7200 && "1 hour ago" || 
     diff < 86400 && Math.floor(diff/3600) + " hours ago") || 
    day_diff == 1 && "Yesterday" || 
    day_diff < 7 && day_diff + " days ago" || 
    day_diff < 31 && Math.ceil(day_diff/7) + " weeks ago"; 

首先,day_diff == 0将评估为false和右手侧:

(diff < 60 && "just now" || 
diff < 120 && "1 minute ago" || 
diff < 3600 && Math.floor(diff/60) + " minutes ago" || 
diff < 7200 && "1 hour ago" || 
diff < 86400 && Math.floor(diff/3600) + " hours ago") 

...未评估。双方:

day_diff == 1 && "Yesterday" 

...评估为false。接着是:

day_diff < 7 && day_diff + " days ago" 

在这个表达式中day_diff < 7的计算结果为true,所以其右手侧,它是一个字符串,将被评估并将其结果返回。

延伸阅读:

http://www.ejball.com/EdAtWork/2005/02/19/JavaScriptBooleanOperators.aspx

1

是啊,这是奇怪的Javascript的东西。字符串连接的计算结果为true,并且prettyDate()底部的return语句在条件中利用了此加号short-circuiting

因此,基本上,在第一种情况下,diff < 60 && "just now"如果diff确实小于60,则计算为字符串“刚才”,因为条件中的所有其他顶级项目都是“或”在一起的,所以Javascript评估程序不会“一旦这个第一个条件成立,就不关心他们。下线也是如此。

1

是打依赖运算符优先级处理条件句危险的游戏:

+胜过&&这胜过||

参见:https://developer.mozilla.org/en/JavaScript/Reference/Operators/Operator_Precedence

这是我读它:

(day_diff == 0 && (
      (diff < 60 && "just now") || 
      (diff < 120 && "1 minute ago") || 
      (diff < 3600 && Math.floor(diff/60) + " minutes ago") || 
      (diff < 7200 && "1 hour ago") || 
      (diff < 86400 && Math.floor(diff/3600) + " hours ago") 
     )) || 
     (day_diff == 1 && "Yesterday") || 
     (day_diff < 7 && day_diff + " days ago") || 
     (day_diff < 31 && Math.ceil(day_diff/7) + " weeks ago"); 
1

该行的最后一条语句有形式

return boolExpression && otherBoolExpression 

JavaScript时读取此,发生以下情况:

  1. 如果boolExpression如果falsey,然后返回boolExpression
  2. 否则,返回otherBoolExpression

这是JavaScript做短路逻辑的方法。

因为在这种情况下,otherBoolExpression使用字符串连接,该函数返回字符串,只要dayDiff不为0

2

return语句只是一个复杂的if/else级联,最终在所有非错误情况下返回一个字符串。

E.g.

return day_diff == 0 && (
     diff < 60 && "just now" || 
     diff < 120 && "1 minute ago" || [...] 

如果day_diff是零(指日期为当天),那么它落入检查,看它是否小于60。如果这种说法是真的,那么它将短路评价的休息整个事情,并返回表达式,这将是“刚才”的值。如果差值不小于60,则会短接子表达式,并继续进行diff < 120检查,依此类推。

表达式中的字符串总是“真”,并且它们也成为在该大小写匹配时评估表达式的结果。

这是功能性但相当模糊的代码。不是用于教学目的。 :)

0

有两个变量:差异 - 以秒为单位的差异,以天为单位的差异。 如果daydiff为零,则返回值基于diff,否则为天数。

将'return'作为决定返回字符串的'if'/'else'子句的系列读取。

1

基本上你只需要知道

return day_diff == 0 && "lala" + "lolo" 

将返回lalalolo如果day_diff == 0 ...因为运算符优先级。

所以它只是一个写

if (day_diff == 0) { 
    if (diff < 60) { 
     return "just now" 
    } else (...) 
} else { 
    if (day_diff == 1) { 
    return "..." 
    } 
} 
7

你是一个Java的人更短的方法是什么?因为如果是这样,你可能认为if(x)需要x是一个布尔值,并且“x & & y”返回一个布尔值。它不适用于JavaScript和许多其他语言,如Perl。在许多弱类型语言中,& &被称为保护运算符,被称为默认操作符。他们返回他们两个论点中的一个。

相关问题