Как стать автором
Обновить

Комментарии 78

Приятно читать, что в крупных компаниях решают некоторые задачи так же, как и ты сам.
В крупных компаниях работают такие же люди как и вы. Не боги горшки обжигают :)
Зато они занимаются пониманием того, что нужно делать :-)
НЛО прилетело и опубликовало эту надпись здесь
С классом local-time? Самое медленное решение, какое можно было придумать.
Либо делать span с id, либо обернуть в <sсript>var local_time = 12345;</sсript>
НЛО прилетело и опубликовало эту надпись здесь
span.local-time не быстрее чем .local-time (вообще не все однозначно)
ссылка, и еще ссылка, и еще.
Про неоднозначность скорости span.local-time и .local-time уже написали.

С уточнением понял, что вы делаете. Тогда всё ок, красивое решение.
Изначально подумал, что таким способом как в статье получаете единственное значение server_timestamp.
Не очень понимаю, что мешает не ползать по DOM каждый раз, а один раз подготовить список элементов для отображения времени?
В таком случае разница во времени работы между различными селекторами невелика.
Нахожусь в Хельсинки, где проходят матчи, время показывает на час меньше, чем на самом деле
Город пишет правильно?
На главной Mail.ru выводится сейчас «Хельсинки пятница, 11 мая, 14:51» хотя на самом деле уже 15:51
Спасибо, разбираемся.
Если в личку еще IP скажете совсем будет хорошо.
Да нет разницы какой у меня ip, если зайти с московского сервака и выбрать Финляндия то точно также показывает время с отставанием на час. Зимой разница 2 часа, летом 1 час, вы еще живете по зимнему времени, а уже лето
Ох уж этот нанопрезидент, мы же теперь часы не переводим.
Вот и багрепорт)
fixed
var begin = new Date().getTime();

function get_delta(){
    return new Date().getTime() - begin;
}


Разве begin попадает в scope функции?
Да
Почитал комментарии. Я не прав, а прав Volshebnyi, которого почему то заминусовали. Переменная begin видна в get_delta, но scope внутри этой функции отнюдь не window, а свой собственный. Пример:

var begin = 1;

function get_delta()
{
  console.log( begin ); // 1
  var some = 2;
}

get_delta();
console.log( some ); // Undefined variable: some

На практике может возникнуть ситуация, когда какой-то код нужно выполнить в другом scope. В частности мне нужно было выполнить код в scope window, притом что сам код выполняется (eval) в функции. В jQuery для этого есть следующий код:

( window.execScript || function( data ) {
	window[ "eval" ].call( window, data );
} )( data );

Насколько я помню он применяется в $.getScript.
Вы всё напутали)
Ок, тогда развейте моё невежество :) Тут и вправду, легко запутаться. Является ли scope для переменной — та область пространства, где эта переменная могла быть определена через var? Я исхожу из этого, и тогда получается что для внутри функции scope всегда она сама.
Почитайте, например, вот это: habrahabr.ru/post/38642/
Ещё можно сделать вот что:


Простым языком.
У каждой функции есть своя область видимости.
Но подфункции имеют доступ к области видимости функции, в которой они объявлены. Это называется «Замыкание».
Через .call(object) меняется не scope функции, а контекст, т.е. на что ссылается this.
Все примеры с eval и аналогами — магия, потому предлагаю их даже не рассматривать, т.к. на практике они имеют мало смысла и к теме обсуждения относятся мало — только запутают.

На вопрос, который задали изначально:
var begin = new Date().getTime();

function get_delta(){
    return new Date().getTime() - begin;
}


Разве begin попадает в scope функции?

Правильный и дотошный ответ такой:

1. Нет, она находится в scope функции выше или в глобальном scope, зависимо от кода. Например вот:
(function test () {
  var begin = new Date().getTime();
  
  function get_delta(){
      return new Date().getTime() - begin;
  }
})()


В данном случае она находится в scope функции test

НО

человек задал вопрос подразумевая другое. Можно ли получить это значение в подфункции get_delta.

Да, т.к. функция является замыканием и имеет доступ к scope функции test. Т.е. можно сказать, что begin видим в функции get_delta хотя и находится в scope родительской функции.
Получается так?
begin попадает в scope функции?
Нет, но попадает в scope выше, который доступен внутри функции.
begin попадает в scope внутри функции?
Да, см. ^выше^.

Ведь если верить вашему скриншоту, т.е. верить гуглу, то scope какой-либо области кода это и closure's и local's, а не только local's.

Касательно .call и .apply, не понял к чему вы :) Я вроде про них и не заикался. А пример про eval не такой уж и гипотетический. Я использовал его вне $.getScript. Спасибо вам, теперь буду знать что сие есть контекст, а не scope.
Ну просто сумбурненько как-то у вас вышло. )
Нет, не попадает, он находится в scope уровнем выше, очевидно же.
Другой вопрос — зачем ему вообще попадать в scope функции get_delta?
Это называется замыкание, одна из моих любимых фич js и groovy
НЛО прилетело и опубликовало эту надпись здесь
Усомнился было в том, что неправильно употребляю термин.

Но, судя по определению в вики, я прав.
Замыкание (англ. closure) в программировании — процедура или функция, в теле которой присутствуют ссылки на переменные, объявленные вне тела этой функции и не в качестве её параметров (а в окружающем коде).
ru.wikipedia.org/wiki/%D0%97%D0%B0%D0%BC%D1%8B%D0%BA%D0%B0%D0%BD%D0%B8%D0%B5_(%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5)
Вы согласны с тем, что Bobry привел отличный пример замыкания?
мне кажется куски кода о которых идет речь немного выдраны из контекста по этому видимо нельзя однозначно сказать замыкание это или нет. ИМХО.
Это замыкание «по определению».

Ну вот как в курсе высшей математики помню, лектор на вопрос студента «а почему эта штука — XXX?»
Отвечает: «По определению штуки XXX.»
если так, то тогда все ф-ции в JS это замыкания, они же удовлетворяют вашим (или из ВИКИ) определению.
Вы абсолютно правы. Это и прекрасно в js :)
Топик: учимся делать замыкания.

function(){}

Спасибо за внимание!
Упс. Вижу свою ошибку.
"в теле которой присутствуют ссылки на переменные"
Не во всех же присутствуют ссылки… Извините.

В общем, все и так прекрасно знают js.
Да, согласен.

Не знаю, будет ли работать такой код в Си.
Такой пример будет работать в Си, но для приведённого выше примера, это наверное всё-таки не замыкание, а глобальная переменная.
Дело не в коде, а в архитекруте языка, если в JS все внешние переменные попадают в нутрь функций, это не значит что в С такой же код будет вести себя аналогично. И да, это называется замыкание, функция замыкает в себе внешнюю облать видимости.
Извините, в упор не вижу замыкания. Все что я вижу — функция видит скоп, в котором находится. Или это и называется замыканием с этого дня?
>>Или это и называется замыканием с этого дня?

В таком случае приведите собственное определение замыкания и его пример в жизни.

Я лишь отталкиваюсь от общепринятого термина. гугл
я согласен с Damaskus

а вам Snowindy я и говорил ранее что пример о котором идет спор выдран из контекста и именно по этому, если представить что это все что есть в коде программы, то это не замыкание ни разу.
10+1 раз подумал… видимо я был не прав.
Функция которая видит scope, в котором описана, и есть замыкание.
Переменные описанные внутри замыкания снаружи не видны (closure от close, т.е. закрыты, не?).
Пример с фубаром не самый удачный, надо сказать.

Ну, на самом деле да. Тут я был не прав, признаю =)
Как легко сморозить глупость в ответ на чужую.
Ох елке, я и не ожидал такой реакции. Давайте еще раз:

var bar = 5;

function foo(){
  alert(bar);
}


В каком скопе находится переменная bar — foo или window?
window
Спасибо, я уже начал сомневаться в своей адекватности, глядя на количество несогласных с этим.
С вами всё в порядке. Я тоже удивился количеству минусов к адекватному и, главное, правильному комментарию. Но что поделать — это хабр :)
В обоих. Если сделаете:

var bar = 5;

function foo(){
  bar = 3;
}

foo();

alert(bar);


Увидите интересный результат.
Точнее, не так:
функция foo() начинает работать с переменными, определенными в более глобальной области, если не используется конструкция var для этих переменных.
А что ж вы мелочитесь-то? Может тут где-то и третий scope есть?
Переменная находится исключительно в scope window.
не правда ваша! в window оно находится, опять-таки так можно утверждать видя весь остальной код. А если считать что все что тут написано это весь код то в window.

в foo она бы была если б была бы объявлена вместо с var, тогда бы эта переменная была бы локальная для foo

а так она принадлежит window.
Спасибо. Я уже сделал уточнение. Тоже немного косное, конечно.
Что-то я не понимаю, у вас есть timestamp на сервере и есть timestamp на клиенте, если отнять одно от другого, то вы разве не поучите разницу в часовых поясах?
Нет, у клиента может быть установлено неверное время.
Если у него неверное время, он всё равно пропустит матч =)
Он может увидеть на сайте, что матч только-только начался. Это его очень выручит.
А может увидеть что матч через 42 года
Для этого и делается синхронизация с сервером. Чтобы на странице текущее время и время начала матча отображались верно. Или я не понял ваше замечание.
это я к тому что нельзя брать разницу между timestamp на сервере и на клиенте.
Понятно. Тогда ваш комментарий был не для меня. Я и не предлагал вариант с разницей timestamp-ов. :)
Мне вот было бы прикольно, если бы именно был еще столбец, где написано «по вашим часам». Т.е. прямо по моим часам на компе. Пусть у меня на 3 минуты даже спешат часы и т.п. Всё вроде честно.
Тогда ему можно выводить абсолютное время до начала матча. Например, «До начала матча осталось 2:12»
А если запрос будет обрабатываться больше часа? :)
Чего-то вы намудрили на ровном месте.
Почемубы просто не дорисовать метод date.setTimezoneOffset()?
упс! прототип встроенных классов не допиливается.
Я для подобных целей делал «эмулятор» класса Date:
code.google.com/p/serial-experiments-qmax/source/browse/zonaldate.js/trunk/zonaldate.js

Юзалось в гугло-волно-гаджете для отображения свободного времени участников встерчи: в своём поясе, в выбранном поясе, либо в поясе любого участника по выбору.
Помню, был удобный JS для работы с датой, там были полезные плюшки вроде разницы между таймзонами, обнулением времени и прочего. Забыл как называется.
Теперь, если пользователь в Самаре, но выбрал Москву, мы корректируем объект Date на разницу между этими двумя городами.

Вот уже, кажется, год Самара и Москва в одном часовом поясе. Пример не очень удачный. :)
согласен, написал по привычке
А почему не воспользовались Date.UTC?
Хах, забавно, Мейл.ру отстает на час, хабр спешит на час )

Практически невозможно предугадать что у кого с датами происходит.
Нельзя доверять не ip провайдера, не локальной дате.

Тем не менее, простым решением будет следующее (мне видеться так):

1. брать локальную дату пользователя

2. основываясь на полученной дате определить часовой пояс или разницу во времени между пользователем и сервером

3. возле времени написать мелко типо такого: «если дата определилась не правильно, пожалуйста выберите верный часовой пояс(или дать возможность указать свой город, с городом будет попроще)».

Таким образом можно собрать базу соответствия ір к часовому поясу (учитывая % тех кто соврал) и определять часовой пояс исходя из этих записей (в куках хранить нет смысла, аккаунтов на мейл.ру у многих нет, писать в таблицу будет ок)
В каком городе мы отстаем на час?

Брать локальную дату очень хочется, но в общем случае она может быть некорректной.

Город мы даем указывать, и на основе этих данных валидируем базу ip адресов.
ща ок, время пишет что надо.
Похоже в этой ветке я опоздал на праздник жизни.

Но для яваскрипта, в котором по непонятным причинам отсутствует человеческая работа с датами, существует великолепная библиотека Moment JS.
Два вопроса:
— Чем она поможет в данной ситуации?
— Зачем тащить целую библиотеку для задаче по выводу даты пользователю?
Ну, затем, чтобы избавиться от таких конструкций, например:
d.push([date.getHours(), date.getMinutes() < 10? '0' + date.getMinutes(): date.getMinutes()].join(':'));

У нее вообще очень клевые возможности по работе с штампами времени и форматированию.

В вашем случае, возможно, это и бессмысленно. Но заметьте, я никому не навязывал ее использование, просто поделился в тематичной ветке.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории