I have made a dependency injection module. It uses a hack I discovered with default parameters. function (x = SomeDependency) {}
. SomeDependency is not defined, but I can parse its toString (same for class constructors, arrow functions and terse object methods). It's not meant to be supported in the browser, only in Node.
My question: I could not find any documentation on whether arguments are lazily evaluated, does any specification/documentation on this exist? Or is this simply undefined behaviour?
Update:
What I am doing is using undefined default parameters (as in the example above), and parsing the toString of the function/class to find out what they are, then calling the function or newing up the class with injected arguments.
I have made a dependency injection module. It uses a hack I discovered with default parameters. function (x = SomeDependency) {}
. SomeDependency is not defined, but I can parse its toString (same for class constructors, arrow functions and terse object methods). It's not meant to be supported in the browser, only in Node.
My question: I could not find any documentation on whether arguments are lazily evaluated, does any specification/documentation on this exist? Or is this simply undefined behaviour?
Update:
What I am doing is using undefined default parameters (as in the example above), and parsing the toString of the function/class to find out what they are, then calling the function or newing up the class with injected arguments.
Share Improve this question edited Jun 18, 2016 at 6:36 user3654410 asked Jun 17, 2016 at 19:16 user3654410user3654410 4843 silver badges14 bronze badges 5- How do you mean 'evaluated'? As for the actual expressions put in the parens, they have to be evaluated pletely before the function is called, as demonstrated by @naomik. Though you might be wondering about the lazy evaluation by the JS engine itself, whether there is any difference between using an argument in a function and leaving it unused? Now I am, and I cannot answer that. – Aurel Bílý Commented Jun 17, 2016 at 19:23
- "manually parsing the toString of the function/class..." ... :( – Mulan Commented Jun 17, 2016 at 21:19
- naomik: Do you have any other option? :P I'm all ears? And I do agree whole heartedly with the :( ! – user3654410 Commented Jun 17, 2016 at 21:40
-
1
The are not default arguments, they are default initialisers of parameters, and they are not lazily evaluated but just conditionally - whenever the argument is
undefined
. – Bergi Commented Jun 17, 2016 at 21:51 - @Bergi Sweet, I know my terminology was a bit off. But in that case this should work just fine. If you make an answer out of that, I will mark it as the answer to my question. – user3654410 Commented Jun 18, 2016 at 0:18
2 Answers
Reset to default 6Are arguments lazily evaluated?
No, everything in JavaScript is eagerly evaluated (if you excuse short-circuit evaluation of logical operands).
Specifically, the default initialisers of parameters are not evaluated when the parameter is used, they are eagerly evaluated when the function is called. They are however evaluated conditionally - whenever the argument is undefined
, pretty much like the statement in a if
clause would be.
Does any specification/documentation on this exist?
Yes, JavaScript evaluation order is specified in the ECMAScript standard (current revision: http://www.ecma-international/ecma-262/7.0/). There is hardly any undefined behaviour.
Are javascript arguments lazily evaluated?
No. JavaScript uses applicative order evaluation
This is very easy to test too
var foo = ()=> (console.log('foo'), 'foo');
var bar = ()=> (console.log('bar'), 'bar');
var bof = (a,b)=> console.log('bof',a,b);
bof(foo(), bar());
Notice you will see "foo"
and "bar"
appear in the log before bof
is evaluated.
This is because foo
and bar
are evaluated first before the arguments are passed to bof