Может ли кто-нибудь объяснить, как работает Javas Resig pretty.js JavaScript?
http://ejohn.org/files/pretty.js
// 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, или я просто что-то пропустил?
edit: я не спрашивал, как он возвращает значение, я спросил, как он возвращает строку.
return day_diff == 0 && (....)
возвращает логическое значение на любом языке, который я когда-либо использовал.
Ответы
Ответ 1
Он говорит прямо там: return ...
, а затем переходит в длинный вложенный список в основном "inline ifs
".; -)
В Javascript операторы boolean возвращают значение одного из операндов, а не только true
или false
. Например. 0 || 'foo'
возвращает 'foo'
. Эта характеристика используется в сочетании с короткозамкнутым оператором. false && true
не будет оценивать сторону true
и возвращать false
немедленно, так как все выражение должно быть false
.
Ответ 2
В 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
Ответ 3
Вы человек Java? Потому что, если это так, вы, вероятно, думаете, что if(x)
требует, чтобы x было логическим, и что "x && y" возвращает логическое значение. Это не в JavaScript и во многих других языках, таких как Perl. Во многих слабо типизированных языках && называется охранным оператором и || называется оператором по умолчанию. Они возвращают один из двух аргументов.
Ответ 4
Оператор return - это просто сложный каскад if/else, который возвращает строку во всех случаях без ошибок.
например.
return day_diff == 0 && (
diff < 60 && "just now" ||
diff < 120 && "1 minute ago" || [...]
Если day_diff равен нулю (это означает, что дата сегодня), тогда он попадает в чек, чтобы увидеть, если он меньше 60. Если это утверждение истинно, тогда он будет короткозамкнуто оценивать остальную часть всего, и возвращает значение выражения, которое будет "только сейчас". Если diff не менее 60, он будет коротко закоротить суб-выражение и перейти к проверке diff < 120
и т.д.
Строки всегда являются "истинными" в выражениях, и они также становятся результатом оценки выражения, когда этот случай соответствует.
Это функциональный, но довольно запутанный код. Не для учебных целей.:)
Ответ 5
Да, это странный материал Javascript. Конкатенация строк оценивается как true, а оператор return
внизу prettyDate()
использует этот плюс short-circuiting в условных выражениях.
Итак, в первом случае diff < 60 && "just now"
оценивает строку "только сейчас", если diff
действительно меньше 60, потому что все остальные элементы верхнего уровня в условном выражении OR'd вместе, поэтому Javascript оценщик не заботится о них, как только это первое условие выполняется. То же самое происходит по линии.
Ответ 6
Он играет в опасную игру, полагаясь на приоритет оператора для обработки условных выражений:
+
trumps &&
, который превосходит ||
Смотрите: 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");
Ответ 7
Последний оператор строки имеет вид
return boolExpression && otherBoolExpression
Когда javascript читает это, происходит следующее:
- if
boolExpression
если false, то он возвращает boolExpression
- в противном случае он возвращает
otherBoolExpression
.
Это метод JavaScript для логики короткого замыкания.
Так как в этом случае otherBoolExpression
использует конкатенацию строк, функция возвращает строку, пока dayDiff
не равно 0.
Ответ 8
В принципе, вы просто должны знать, что
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 "..."
}
}
Ответ 9
Существуют две переменные: diff - разница в секундах, daydiff - разница в днях.
Если daydiff равен нулю, возвращаемое значение основывается на diff, иначе это количество дней.
Прочитайте 'return' как серию предложений 'if'/'else', определяющих возвращаемую строку.