2011-02-17 99 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。在許多弱類型語言中,& &被稱爲保護運算符,被稱爲默認操作符。他們返回他們兩個論點中的一個。

相關問題