Wat is de volgorde van evaluatie voor functieargumenten in Javascript?

Volgens mijn tests is het altijd van links naar rechts

>> console.log( console.log(1), console.log(2) );
1
2
undefined undefined

maar ik kan de relevante sectie niet vinden die dit bevestigt in de ECMAScript-standaard.

20
console.log (1), console.log (2) zijn argumenten en functies die worden opgeroepen als een zelfuitvoerende functie
toegevoegd de auteur Joe, de bron
Men zou kunnen overwegen dat f (g (0), g (1)) vrijwel gegarandeerd hetzelfde doet als f.apply (thisObj, [g (0), g ( 1)]) . Het is waarschijnlijk een nuttig mentaal hulpmiddel om de twee equivalenten te beschouwen, en misschien is het logischer om het OP te definiëren dat array-elementen in een volgorde van links naar rechts worden gedefinieerd.
toegevoegd de auteur Triptych, de bron
Volgt dit niet de volgorde , en groepering op ( & ) ? Operator Precedence ...
toegevoegd de auteur John Strickler, de bron

3 antwoord

Alle operators in JavaScript evalueren hun operanden van links naar rechts, inclusief de operator voor functieaanroep. Eerst wordt de te bellen functie geëvalueerd en vervolgens de actuele parameters in volgorde van links naar rechts.

Section 11.2.3 is the relevant spec section.

11.2.3 Functieaanroepen

     

...

     

2 Laat func worden GetValue (ref) .

     

3 Laat argList het resultaat zijn van het evalueren van Argumenten , waardoor een interne lijst met argumentwaarden wordt geproduceerd (zie 11.2.4).

     

...

en je kunt zien dat de ArgumentList productie links-recursief is

11.2.4 Argumentlijsten

     

...

     

De productie ArgumentLijst : ArgumentLijst , AssignmentExpression wordt als volgt geëvalueerd

en ArgumentList wordt geëvalueerd vóór AssignmentExpression in de volgende woordenstroom ..

Under EcmaScript 3 some of the comparison operators (<, <=, >, >=) evaluated right to left since a<=b was defined in terms of !(b, but that was widely recognized as a spec error, major interpreters did not implement it that way, and it was fixed in EcmaScript 5.

Uit de taalspecificatie:

11.8.5 The Abstract Relational Comparison Algorithm # Ⓣ

The comparison x < y, where x and y are values, produces true, false, or undefined (which indicates that at least one operand is NaN). In addition to x and y 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 upon x and y. It is necessary because ECMAScript specifies left to right evaluation of expressions. The default value of LeftFirst is true and indicates that the x parameter corresponds to an expression that occurs to the left of the y parameter’s corresponding expression. If LeftFirst is false, the reverse is the case and operations must be performed upon y before x. Such a comparison is performed as follows:

16
toegevoegd
@RightSaidFred: Associativiteit bepaalt alleen of je a op b op c als ((a op b) op c) of (a op (b op c)) disambigueert . Het heeft niets te maken met of a of b eerst wordt geëvalueerd in a op b
toegevoegd de auteur hugomg, de bron
@ ŠimeVidas, de operator voor functieaanroep. ()
toegevoegd de auteur Mike Samuel, de bron
@RightSaidFred, je verwart associativiteit met volgorde van evaluatie. Associativiteit wordt in aanmerking genomen tijdens parse time, maar de volgorde van evaluatie is significant tijdens runtime.
toegevoegd de auteur Mike Samuel, de bron
@RightSaidFred, om dit duidelijk te maken, probeer var x = 1 uit te voeren; (x = []) [0] = x; . x is nu een array die zichzelf bevat, niet een array die 1 bevat omdat de x = [] vóór de meest rechtse x .
toegevoegd de auteur Mike Samuel, de bron
@RightSaidFred, downhotes zijn een feit van het leven. Ik stel de vraag op prijs. Om u te helpen werken, associativiteit is de reden waarom x = y = z hetzelfde is als x = (y = z) maar 1 - 1 - 1 is (1 - 1) - 1 in plaats van 1 - (1 - 1) .
toegevoegd de auteur Mike Samuel, de bron
Van welke operator van OP's code verwijs je?
toegevoegd de auteur Šime Vidas, de bron
"Alle operators in JavaScript evalueren hun operanden van links naar rechts." Dat is gewoon niet correct. developer.mozilla.org/en/JavaScript/Reference/Operators/… Er zijn er genoeg die van rechts naar links evalueren.
toegevoegd de auteur RightSaidFred, de bron
Ik begrijp wat je zegt. Verwerken ... Ik heb je niet in de val gelokt, maar de stemming was misschien mijn fout, dus +1
toegevoegd de auteur RightSaidFred, de bron
@MikeSamuel: Bedankt voor de voorbeelden. Ja, ik begrijp het associativiteitseinde ervan, maar werd er ten onrechte van uitgegaan dat expressieevaluatie de associativiteit volgde. Uw Array-voorbeeld verduidelijkte dat perfect. Nogmaals bedankt!
toegevoegd de auteur RightSaidFred, de bron

Het wordt hier gedefinieerd:

The production ArgumentList : ArgumentList , AssignmentExpression is evaluated as follows:

  1. Let precedingArgs be the result of evaluating ArgumentList.
  2. Let ref be the result of evaluating AssignmentExpression.
  3. Let arg be GetValue(ref).
  4. Return a List whose length is one greater than the length of precedingArgs and whose items are the items of precedingArgs, in order, followed at the end by arg which is the last item of the new list.

Read here: http://es5.github.com/#x11.2.4

Wanneer een functie wordt aangeroepen, worden de doorgegeven argumenten van links naar rechts geëvalueerd.

11
toegevoegd
+1, waarschijnlijk het beste antwoord technisch ...
toegevoegd de auteur Triptych, de bron
Die, maakt het mogelijk om uitspraken te evalueren zoals func (a ++, ++ a, a * = a, a--, --a) . Het is gedefinieerd gedrag dankzij de bovenstaande specificatie, in tegenstelling tot de C-taal. Het is geen goede oefening.
toegevoegd de auteur K._, de bron

Voor historisch belang, zie ook sectie 4.2 Evaluatieorder van JavaScript 1.1 Taalspecificatie (Brendan Eich, C. Rand Mckinney, 18/11/96).

In een functie of constructor aanroep, een of meer argumentuitdrukkingen   kan tussen haakjes verschijnen, gescheiden door komma's. Elk argument   expressie is volledig geëvalueerd voordat een deel van een argument   uitdrukking rechts wordt geëvalueerd.

5
toegevoegd