只是潜伏在140byte docs的奇怪和奇特的东西,找到了this:
void 0
比undefined
快,但比替代品更长。
我懒得在Chrome控制台中检查,如下所示:
console.time('void');
for (let a = 0; a < 1e6; a++) {() => void 0};
console.timeEnd('void');
VS
console.time('undefined');
for (let a = 0; a < 1e6; a++) {() => undefined};
console.timeEnd('undefined');
发现没有区别。也许我的懒惰检查太懒了,或者只是关于缓慢的陈述不再相关了。
我只是想知道JS引擎的内部结构以及它是如何实现的?我们怎样才能谈论原语和运算符的速度?它是否正确且相关?这听起来有点奇怪。
答案 0 :(得分:5)
我只是想知道JS引擎的内部结构以及它是如何实现的?我们怎样才能谈论原语和运算符的速度?它是否正确且相关?这听起来有点奇怪。
是的,这是可能的。 undefined
是全局变量,而不是关键字。这意味着它可以被遮蔽。因此,为了找到它的值,JavaScript引擎需要遍历作用域链并检查每个作用域级别的"undefined"
绑定。例如:
function outer() {
function middle() {
function inner() {
console.log(undefined);
}
inner();
}
middle();
}
outer();
inner
内的引用要求JavaScript引擎检查inner
函数的执行上下文的绑定对象,然后检查middle
,然后检查outer
,最后在全球范围内找到它。
相比之下,void
是void
运算符的关键字,0
是文字,因此void 0
不需要范围链遍历。由于void
运算符定义为始终返回undefined
,因此有一种机制可以使其比undefined
全局更好地执行。
并不是说它可能很重要。你更有可能做其他会影响你表现的事情。
FWIW,一个天真的基准:
var x = undefined;
var now = performance && performance.now ? performance.now.bind(performance) : Date.now.bind(Date);
function outermost() {
var a = Math.random();
function outer() {
var b = Math.random();
function inner() {
var c = Math.random();
function test1() {
if (Math.random() > 1) { // Never true
x = 42;
}
return x == undefined;
}
function test2() {
if (Math.random() > 1) { // Never true
x = 42;
}
return x == void 0;
}
function test(f, n) {
var start = now();
while (n-- > 0) {
f();
}
return now() - start;
}
console.log("Testing...");
setTimeout(function() {
test(test1, 100000000); // warmup
test(test2, 100000000); // warmup
console.log("undefined", test(test1, 1000000000), "ms");
console.log("void 0 ", test(test2, 1000000000), "ms");
}, 40);
if (a + b + c > Infinity) {
console.log("Impossible, just making sure to use a, b, and c");
}
}
inner();
}
outer();
}
outermost();
WARNING: THIS MAY LOCK UP YOUR BROWSER WINDOW.
For me, it runs fine on recent Chrome, taking about 20 seconds; YMMV.