Project: Playing with JavaScript's keyword


Mon Jun 03 15:37:49 GMT-0700 (Pacific Daylight Time) 2024

I had a silly idea about JavaScript's new keyword. You can return whatever you want from a JavaScript constructor. Could you return something different from a constructor when called normally versus with a new keyword? Yes! I found the wild magic property. I say "wild" and "magic" because nothing else in JavaScript works like this. So anyways, what could we do with this magic property?

I had this question: "could I make a function which can generate any number any integer with only a mix of new and parentheses?" That is, if I only mixed the word new and the open and closing paren characters (( and )), could I generate an arbitrary expression which evaluates to an arbitrary integer (whole number)?

So I'd need a recursive constructor. That was simple enough.


And I'd need to differentiate between using the new keyword to call as a constructor or just parentheses to call as a normal function:


I also needed a function which was callable but when used in an expression would evaluate to a number. I found I could achieve this by editing the prototype's valueOf. I also learned with the help of this stack overflow answer that modifying the prototype of a function was possible but slow. Well, I wasn't here to win any speed benchmarks.


With that I felt I had all the tools I needed. I had only to mash them together in various arrangements until the perfect result arose.


Now, obviously, this is ridiculous. And I'm not even using the parameter to the function. What's the need for that?

Also, this is not any integer, since I have no way to make negative numbers. Maybe the parameter could negate the input?

Wed Jun 5 12:40:00 AM PDT 2024

All the code above worked when I tested it in Node locally, but when I pushed this webpage up, I found it failed in the browser:

Uncaught TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them

My fancy script tags defaulted to <script type="module">, and only through this incident did I learn that modules automatically engage strict mode. Interesting! Anyways, I simply switched them to non-module scripts and that seemed to work!

I figured I could also fix this by not using arguments.callee, since I already had a reference to the function name as a closure. But nobody uses arguments.callee anymore, so that added to the funkiness of the experiment.