What is the order of evaluation for function arguments in Javascript?
According to my tests it is always left-to-right
>> console.log( console.log(1), console.log(2) );
1
2
undefined undefined
but I can't find the relevant section confirming this in the ECMAScript standard.
Solution 1:
All the operators in JavaScript evaluate their operands left-to-right, including the function call operator. First the function to call is evaluated then the actual parameters in left-to-right order.
Section 11.2.3 is the relevant spec section.
11.2.3 Function Calls
...
2 Let func be GetValue(ref).
3 Let argList be the result of evaluating Arguments, producing an internal list of argument values (see 11.2.4).
...
and you can see that the ArgumentList production is left-recursive
11.2.4 Argument lists
...
The production ArgumentList : ArgumentList
,
AssignmentExpression is evaluated as follows
and ArgumentList is evaluated before AssignmentExpression in the following verbiage..
Under EcmaScript 3 some of the comparison operators (<
, <=
, >
, >=
) evaluated right to left since a<=b
was defined in terms of !(b<a)
, but that was widely recognized as a spec error, major interpreters did not implement it that way, and it was fixed in EcmaScript 5.
From the language spec:
11.8.5 The Abstract Relational Comparison Algorithm # Ⓣ
The comparison
x < y
, wherex
andy
are values, producestrue
,false
, orundefined
(which indicates that at least one operand isNaN
). In addition tox
andy
the algorithm takes a Boolean flag named LeftFirst as a parameter. The flag is used to control the order in which operations with potentially visible side-effects are performed uponx
andy
. It is necessary because ECMAScript specifies left to right evaluation of expressions. The default value of LeftFirst is true and indicates that thex
parameter corresponds to an expression that occurs to the left of they
parameter’s corresponding expression. If LeftFirst is false, the reverse is the case and operations must be performed upony
beforex
. Such a comparison is performed as follows:
Solution 2:
It's defined here:
The production
ArgumentList : ArgumentList , AssignmentExpression
is evaluated as follows:
- Let
precedingArgs
be the result of evaluatingArgumentList
.- Let
ref
be the result of evaluatingAssignmentExpression
.- Let
arg
beGetValue(ref)
.- Return a List whose length is one greater than the length of
precedingArgs
and whose items are the items ofprecedingArgs
, in order, followed at the end byarg
which is the last item of the new list.
Read here: http://es5.github.com/#x11.2.4
When a function is invoked, the passed-in arguments are evaluated from left to right.
Solution 3:
For historical interest, also see section 4.2 Evaluation Order of JavaScript 1.1 Language Specification (Brendan Eich, C. Rand Mckinney, 11/18/96).
In a function or constructor call, one or more argument expressions may appear within the parentheses, separated by commas. Each argument expression is fully evaluated before any part of any argument expression to its right is evaluated.