让var o = {a:Date.now(), b:Date.now()}
。
o.a === o.b
总是true
吗? (我最感兴趣的是Node.JS。)
答案 0 :(得分:21)
没有
在我们进入规范可能会说的内容之前,getHeight()
可以在运行时用用户定义的函数替换。这适用于Node和浏览器:
Date.now
这样,每次调用至少需要一秒钟,所以你的两次调用永远不会相等。
当我们查看the spec for Date.now
(15.9.4.4)时,它只是说它返回
指定现在发生呼叫的UTC日期和时间的时间值
,它不保证两次调用返回相同的值。据我所知,the spec specifies that Date
objects will have millisecond precision (15.9.1.1)但不保证准确性。
同一行中的两个调用很可能可能返回相同的时间,因为底层计时器不精确且两个发生在相同的时间内,但规范没有出现指定。
答案 1 :(得分:9)
不,试试这个简单的测试:
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 !=');
}
}
你会看到会发生什么!
答案 2 :(得分:5)
即使两者可能始终相同 - 某些JS-engine-implementation-wise,逻辑上它是两个不同的时间瞬间,这就是我对待它们的方式。
答案 3 :(得分:3)
如果你对精确度感兴趣,我建议使用performance.now()。 如果你需要它们是相同的,我建议为对象编写一个构造函数,然后将Date.now()分配给一个临时变量,然后将该值赋给a和b。 < / p>
以下是API Discovering the HR Time API
上的入门手册以下是一些特定于节点的信息:Node hrtime
答案 4 :(得分:2)
没有
您的问题暗示了两个问题:
对象初始值设定项是否存在特殊内容,它们会查看属性初始值设定值以及&#34;优化&#34;他们或者什么来避免多余的电话?
快速连续两次调用时,Date.now
是否会返回相同的值?
答案是否定的,不是。 :-)让我们更详细地看一下:
逐步处理对象初始值设定项。这在规范(start here)中有详细说明,虽然在之前的第5版规范中它更容易理解很多,但它基本上表示创建了对象,然后属性是在源代码顺序中添加,一次添加一个。所以:
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);
&#13;
<!-- 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>
&#13;
... a
可靠地获得0
,b
可靠获得1
。
因此,我们知道:
var o = {
a: Date.now(),
b: Date.now()
};
...将Date.now
两次拨打,一个接一个,快速连续。是时候看看了......
Date.now
快速连续调用对Date.now
的两次调用,一次接一次,确实可以返回不同的值;它甚至都不是那么罕见。它是一个基于时间的功能。如果你在毫秒时间变化的任何一方打电话,你会得到不同的价值观。现在一台计算机需要很长的时间,但并非所有的 很长。
我们很容易证明它是凭经验发生的:
var first, second;
var counter = 0;
snippet.log("Start");
do {
first = Date.now();
second = Date.now();
++counter;
} while (first === second);
snippet.log("Stop, values were different: " + first + " !== " + second + "; counter = " + counter);
var first, second;
var counter = 0;
snippet.log("Start");
do {
first = Date.now();
second = Date.now();
++counter;
} while (first === second);
snippet.log("Stop, values were different");
snippet.log(first + " !== " + second);
snippet.log("counter = " + counter);
&#13;
<!-- 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>
&#13;
以上总是停止,证明快速连续的两个调用将返回不同的值。对我来说,在Linux上的Chrome上,counter
通常都不高(通常为4位,有时为3位,有时为5位)。
我们也知道它来自the specification,其中说:
now
函数返回一个数字值,该值是指定调用now
时发生的UTC日期和时间的时间值。
(我的重点)因此,规范的合规实施不能在开始JavaScript之前做出决定&#34; job&#34; now
的价值是什么,然后在整个工作中重复使用。这与规范相反。
因为我们知道对象初始值设定项中的属性初始值设定项是一个接一个地处理的,并且对Date.now
进行了两次单独的调用,并且我们知道对Date.now
的两次调用可能返回不同的值,我们知道对于var o = {a:Date.now(), b:Date.now()}
,o.a === o.b
将不始终为真,在NodeJS(例如,V8)或遵循规范的任何其他JavaScript引擎