在求职面试中,我很难听到“javascript可以无序评估陈述”。这到底是什么程度的?我可以想象一百种方法来明确地无序地评估语句 - 例如在分时操作系统中。但他似乎说,如果我评价
console.log('a')
console.log('b')
Javascript规范以某种方式不要求输出先是a
然后b
。我可以想象,如果语句在功能上是纯的,即没有副作用,但是副作用必须始终按顺序发生,那么评估者可能尝试来评估第二个语句?当然,IO是一个很大的副作用。
规范兼容的Javascript在多大程度上可以无序评估?或者这是一个误传的情况?
答案 0 :(得分:7)
JavaScript是单线程的(除了Web工作者)。期。 ECMA-262 Language Specification Edition 5.1没有提到无序执行。在您的简单示例中,这两个语句保证以相同的顺序执行。
此外,单个JavaScript代码块永远不会被任何其他代码块中断,例如事件处理程序这就是为什么长时间运行的代码块会导致UI 冻结:
for(var i = 0; i < 1000000000; ++i) {
console.log(i);
}
保证上面的代码块永远不会被中断或重新排序。只要循环正在运行,所有事件处理程序和超时都等待单个线程。当然,数字会以正确的顺序出现。
可能无序执行的是异步超时:
setTimeout(function() {
console.log('a');
}, 1);
setTimeout(function() {
console.log('b');
}, 1);
在这里,您可能希望首先打印a
,但JS引擎可能会重新排序这些事件。毕竟你安排这些调用几乎在同一时间点执行。
答案 1 :(得分:2)
显然是误传。
这个家伙可能指的是JavaScript吊装。您可以在此处详细了解:http://www.adequatelygood.com/2010/2/JavaScript-Scoping-and-Hoisting
此外,您可以在此处了解该语言的更多特性:http://bonsaiden.github.com/JavaScript-Garden/
答案 2 :(得分:1)
在大多数情况下,是的。有两个主要的例外(撇开明显的“定义函数,调用函数”,它有效地“返回”函数体):
1:吊装。 var
语句被悬挂,所以如果你写
alert(a);
var a = 123;
您获得undefined
,而不是错误消息。这是因为它被提升到了
var a;
alert(a);
a = 123;
同样,函数定义也被提升。如果你写:
foo(123);
function foo(num) {alert(num);}
它会起作用,因为该功能是悬挂的。但是,如果你写了
,这不起作用foo(123);
foo = function(num) {alert(num);}
因为这是一个匿名函数的赋值,而不是函数定义。
2:异步功能。
初学者的一个常见错误是写下这个:
var a = new XMLHttpRequest();
a.open("GET","sompage.php",true);
a.onreadystatechange = function() {
if( a.readyState == 4 && a.status == 200) {
myvar = "Done!";
}
};
a.send();
alert(myvar);
他们希望警报说Done!
,但是他们会因为没有被定义而得到一个莫名其妙的错误。这是因为myvar = "Done!"
尚未运行,尽管在剧本中较早出现。
另见Computer Stupidities的这个轶事:
一位入门编程学生曾经让我看看他的程序,并弄清楚为什么它总是因为简单的计算而产生零。我查看了该程序,这很明显:
begin readln("Number of Apples", apples); readln("Number of Carrots", carrots); readln("Price for 1 Apple", a_price); readln("Price for 1 Carrot", c_price); writeln("Total for Apples", a_total); writeln("Total for Carrots", c_total); writeln("Total", total); total := a_total + c_total; a_total := apples * a_price; c_total := carrots + c_price; end;
- 我:“好吧,你的程序在计算之前无法打印出正确的结果。”
- 他:“嗯?合适的解决方案是合乎逻辑的,计算机应该以正确的方式重新排列指令。”
答案 3 :(得分:0)
我认为他们试图让你走错了路。 Javascript是有序的。否则计算值的函数将无效。可能是真的是console.log
激活Async task
,这意味着它可以以不同的顺序执行。与Ajax
来电相似,可以是Webworker
,timeout
或interval
。
如果你执行以下操作,它将导致B而不是A,这不是一个顺序代码,因为在代码中。 A代表B,但B先执行。
setTimeout(function(){
console.log("A")
}, 5);
console.log("B");