最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Is order of evaluation sequential in Javascript? - Stack Overflow

programmeradmin0浏览0评论

At a job interview, I was perplexed to hear "javascript can evaluate statements out of order." To what degree is this true? I can imagine a hundred ways to explicitly evaluate statements out of order -- such as in a time-sharing operating system. But he seemed to say that if I evaluate

console.log('a')
console.log('b')

that the Javascript spec somehow doesn't require that the output would be a first then b. I can imagine that the evaluator might try to evaluate the second statement if the IO of the first is blocking if the statements are functionally pure, i.e. no side effects, but side effects must always occur in sequence, correct? And of course IO is one big side effect.

To what extent can spec-pliant Javascript evaluate out of order? Or was this a case of mismunication?

At a job interview, I was perplexed to hear "javascript can evaluate statements out of order." To what degree is this true? I can imagine a hundred ways to explicitly evaluate statements out of order -- such as in a time-sharing operating system. But he seemed to say that if I evaluate

console.log('a')
console.log('b')

that the Javascript spec somehow doesn't require that the output would be a first then b. I can imagine that the evaluator might try to evaluate the second statement if the IO of the first is blocking if the statements are functionally pure, i.e. no side effects, but side effects must always occur in sequence, correct? And of course IO is one big side effect.

To what extent can spec-pliant Javascript evaluate out of order? Or was this a case of mismunication?

Share Improve this question asked Jan 31, 2013 at 20:07 CuadueCuadue 3,9493 gold badges27 silver badges38 bronze badges
Add a ment  | 

4 Answers 4

Reset to default 8

JavaScript is single threaded (web workers aside). Period. ECMA-262 Language Specification Edition 5.1 says nothing about out-of-order execution. In your simple example these two statements are guaranteed to be executed in the same order.

Moreover, single block of JavaScript code will never be interrupted by any other block of code, e.g. event handler. That's why long running blocks of code cause UI to freeze:

for(var i = 0; i < 1000000000; ++i) {
    console.log(i);
}

It's guaranteed that the block of code above will never be interrupted or reordered. As long as the loop is running, all event handlers and timeouts wait for single thread. And of course, numbers will appear in correct order.

What might be executed out-of-order is an asynchronous timeout:

setTimeout(function() {
    console.log('a');
}, 1);
setTimeout(function() {
    console.log('b');
}, 1);

Here you might expect a to be printed first, but it's possible that JS engine will reorder these events. After all you schedule these calls to execute at almost the same point in time.

Clearly mismunication.

The dude was maybe referring to JavaScript hoisting. You can read more about it here : http://www.adequatelygood./2010/2/JavaScript-Scoping-and-Hoisting

Furthermore, you can learn more particularities of the language here: http://bonsaiden.github./JavaScript-Garden/

For the most part, yes. With two major exceptions (leaving aside the obvious "define a function, call the function" which effectively "goes back" to the function body):

1: Hoisting. var statements are hoisted, so if you write

alert(a);
var a = 123;

You get undefined, and not an error message. This is because it is hoisted to

var a;
alert(a);
a = 123;

Similarly, function definitions are hoisted too. If you write:

foo(123);
function foo(num) {alert(num);}

It will work, because the function is hoisted. However, this does NOT work if you wrote

foo(123);
foo = function(num) {alert(num);}

Because that's an assignment of an anonymous function, not a function definition.

2: Asynchronous functions.

A mon mistake among beginners is to write this:

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);

They expect the alert to say Done!, but instead they get an inexplicable error about it not being defined. This is because the myvar = "Done!" hasn't been run yet, despite appearing earlier in the script.


See also this anecdote from Computer Stupidities:

An introductory programming student once asked me to look at his program and figure out why it was always churning out zeroes as the result of a simple putation. I looked at the program, and it was pretty obvious:

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;
  • Me: "Well, your program can't print correct results before they're puted."
  • Him: "Huh? It's logical what the right solution is, and the puter should reorder the instructions the right way."

I think they tried to put you on your wrong foot. Javascript is sequensial. Otherwise functions where you calculate values won't work out. What can be true is that console.log activates an Async task which means it can be executed in a different order. Like an Ajax call, a Webworker, a timeout or an interval.

If you do the following it will result B than A, this is not a sequensial code because in code. A es for B but B is executed first.

setTimeout(function(){
    console.log("A")
}, 5);
console.log("B");
发布评论

评论列表(0)

  1. 暂无评论