Два Date.now() в одном объявлении объекта
Пусть var o = {a:Date.now(), b:Date.now()}
.
Является ли o.a === o.b
всегда true
? (Меня больше всего интересует Node.JS.)
Ответы
Ответ 1
Нет.
Прежде чем мы даже поймем, что спецификация может сказать, Date.now
можно заменить на пользовательскую функцию во время выполнения. Это работает как в Node, так и в браузерах:
let oldNow = Date.now;
Date.now = function () {
let wait = oldNow() + 1000;
while (oldNow() < wait) {
// wait one second
}
return oldNow();
}
При этом каждый вызов будет занимать не менее одной секунды, поэтому ваши два вызова никогда не будут равны.
Когда мы смотрим на спецификацию для Date.now
(15.9.4.4), она просто говорит, что возвращает
значение времени, обозначающее дату и время UTC наступления вызова на данный момент
который не гарантирует никаких двух вызовов, возвращающих одно и то же значение. Из того, что я могу сказать, спецификация указывает, что объекты Date
будут иметь миллисекундную точность (15.9.1.1), но не дает никаких гарантий относительно точности.
Вероятно, что два вызова в одной строке, вероятно, вернутся в одно и то же время, в силу того, что основной таймер является неточным, а два встречаются в одном тике, но спецификация не указала это.
Ответ 2
Нет, попробуйте этот простой тест:
var test = new Array();
for(var i=0; i<40000; i++){
test.push({a:Date.now(), b:Date.now()});
}
for(var i=0 ; i<test.length; i++){
if(test[i].a != test[i].b){
console.warn('a & b !=');
}
}
И вы увидите, что произойдет!
Ответ 3
Даже если оба из них всегда могут быть похожими на JS-engine-реализацию, логически это два разных момента времени и то, как я буду относиться к ним.
Ответ 4
Если вы заинтересованы в точности, я бы предложил performance.now(). Если вам нужно, чтобы они были одинаковыми, я бы предложил написать конструктор для объекта, а затем присвоить Date.now() временной переменной, а затем присвоить это значение как a, так и b.
Вот праймер в API Обнаружение API HR Time
Вот некоторая node -специфическая информация: Node hrtime
Ответ 5
Нет.
В вашем вопросе подразумевается два вопроса:
-
Есть ли что-то особенное в инициализаторах объектов, которые смотрят на значения инициализатора свойств и "оптимизируют" их или что-то, чтобы избежать избыточных вызовов?
-
Будет ли Date.now
всегда возвращать одно и то же значение при вызове дважды в быстрой последовательности?
Ответы нет, и нет.:-) Давайте посмотрим более подробно:
Инициализаторы объектов
Инициализаторы объектов обрабатываются поэтапно. Это подробно описано в спецификации (начало здесь), и хотя это было лот, легче понять в предыдущем 5-м редакция spec, в основном говорится, что объект создан, а затем свойства добавляются к нему в порядке исходного кода, по одному за раз. Итак:
var o = {
a: "one",
b: "two"
};
Сначала движок JavaScript создает объект, затем он оценивает правую часть инициализатора свойств для a
("one"
), добавляет свойство a
к результирующему значению, затем оценивает правый стороне инициализатора свойств для b
("two"
), затем добавляет свойство b
к результирующему значению. Итак, мы знаем, что правые части оцениваются отдельно и в отдельные моменты процесса. Вот почему:
var value = 0;
function unique() {
return value++;
}
var o = {
a: unique(),
b: unique()
};
var value = 0;
function unique() {
return value++;
}
var o = {
a: unique(),
b: unique()
};
snippet.log("o.a = " + o.a + ", o.b = " + o.b);
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>