Dissecting a JavaScript Quine

Computer Science, JavaScript,

Illustration: Hachibu

Introduction

What do you think the following program does?

$ cat quine.js
!function $() {
  console.log('!' + $ + '()')
}()

If you’re feeling confused then you’re not alone because I felt the same way when I found this cryptic collection of characters (otherwise known as code). In esoteric computer science circles, this is considered a Quine, which is a program that:

  • takes no input.
  • produces its own source code.

So, the output of the Quine above is itself a Quine. How strange is that?

$ node quine.js
!function $() {
  console.log('!' + $ + '()')
}()

And because Quines are self-reproducing, I can repeatedly pipe the output of the Quine above back into the Node interpreter and still end up with a Quine.

$ node quine.js | node | node | node
!function $() {
  console.log('!' + $ + '()')
}()

Furthermore, there exist several Quine variations that are even more inscrutable, such as Quine Relays, Multiquines and Radiation-hardened Quines.

How It Works

1!function $() {
2  console.log('!' + $ + '()')
3}()

As it happens, Quines can be a useful, low-emission vehicle for learning. In my effort to examine this Quine, I discovered 2 curiosities about the JavaScript language that allow this Quine to function.

  • On line 1, notice the not operator (!) before the function definition and invocation. Placing the not operator before an expression will evaluate that expression and then negate the result.

    !function() { return true }() // => !true => false
    

    Therefore, the not operator on line 1 causes the function ($) to execute, which then triggers the console.log.

  • On line 2, notice the string concatenation inside of the console.log. Whenever a string is concatenated with a non-string object, JavaScript will cast that object into a string by calling the toString method on that object. Line 2 could be rewritten like this, and it would behave the same.

    console.log('!' + $.toString() + '()')
    

    The function toString method is really interesting, because it will print the function’s source code with comments, newlines and indentation intact. This is the main reason why this Quine is so concise; self-reflection is built into the JavaScript language.

    > function func() {
    ... return true
    ... }
    > func.toString()
    'function func() {\nreturn true\n}'
    

Conclusion

Quines might be impractical, but the techniques required to implement them are not. For example, AngularJS (v1.x) relied heavily on the function toString method to implement dependency injection, and many JavaScript minifiers compress immediate function invocation by using the not operator.

Thank you to Jordan Winick, MarĂ­n Alcaraz and Michael Geraci for editing.
If you liked this post, you might also like Write Your Own JavaScript Template Tag or Keyboard Events TL;DR.