找回密码
 立即注册
首页 业界区 业界 JavaScript Quine揭秘:如何让程序输出自身源代码? ...

JavaScript Quine揭秘:如何让程序输出自身源代码?

僚娥 2025-7-2 19:11:58
介绍

如何写一段javascript程序,输出自身的源代码?这个问题非常有意思,大家不妨先尝试一下,反正在尝试了半个小时之后,我果断放弃了。
这种能输出自身的程序在英文里被称为quine。
准备知识

其实要实现这样一段程序,至少要掌握javascript中两个重要的知识点:

  • IIFE
  • toString()方法
关于IIFE,之前的文章已经做过详细的介绍,这里就不再赘述了,感兴趣的同学可以先去看一下。
JavaScript IIFE揭秘
关于toString()方法,相信大家也不陌生,但是你可知道对于一个函数来说,调用toString()方法意味着什么?
没错,调用一个函数的toString()方法会返回这个函数的源代码。
  1. function foo() {
  2.   console.log('hello world')
  3. }
  4. console.log(foo.toString()) // 输出foo的源代码
复制代码
第一个例子

有了上面的知识储备,我们可以动手写一下了,首先写一个函数foo,在函数体内调用console.log(foo.toString())输出函数的源代码。
  1. function foo() {
  2.   console.log(foo.toString())
  3. }
复制代码
但是这只是函数定义,并未执行,所以需要在函数定义之后调用它。
  1. function foo() {
  2.   console.log(foo.toString())
  3. }foo() // 调用函数,输出源代码
复制代码
运行上面的代码,输出的结果如下所示,可以看到最后的调用语句foo()并没有打印出来。
  1. function foo() {
  2.   console.log(foo.toString())
  3. }
复制代码
这不符合我们的要求,所以考虑去掉调用语句,将函数改为IIFE的形式
  1. (function foo() {
  2.   console.log(foo.toString())
  3. })()
复制代码
运行上面的代码,输出的结果如下,最外层的()和末尾调用函数的()没有打印出来,这也不符合我们的要求。
  1. function foo() {
  2.   console.log(foo.toString())
  3. }
复制代码
改造一下内部的console.log,将两组括弧也输出来。
  1. (function foo() {
  2.   console.log('(' + foo.toString() + ')()')
  3. })()
复制代码
这回结果终于正确了,我们进一步改造,使用+拼接字符串时,js会自动将+另一侧的操作数转换为字符串,所以我们可以把toString()省略掉。
  1. (function foo() {
  2.   console.log('(' + foo + ')()')
  3. })()
复制代码
再增加点神秘感,将foo换成$
  1. (function $() {
  2.   console.log('(' + $ + ')()')
  3. })()
复制代码
运行结果如下:
  1. (function $() {
  2.   console.log('(' + $ + ')()')
  3. })()
复制代码
这就是一个简单的javascript quine了。
最短的例子

在上面的例子中,为了便于观察结果,使用了console.log输出了源代码,实际上我们可以直接返回源代码,这样就可以省略掉console.log语句。
  1. (function $() {
  2.   return '(' + $ + ')()'
  3. })()
复制代码
根据前面两篇文章学到的IIFE的知识,我们使用IIFE的箭头函数形式。下面这段代码定义一个箭头函数并将其赋值给变量$,然后立即执行这个函数。
  1. ($ = () => {
  2.   return '(' + $ + ')()'
  3. })()
复制代码
但是它的执行结果中没有包含$,我们加上$
  1. ($ = () => {
  2.   return '($ =' + $ + ')()'
  3. })()
复制代码
根据箭头函数的规则,如果返回值只有一行,那么可以省略掉大括号{}和return关键字,所以我们可以进一步简化为
  1. ($ = () => '($ =' + $ + ')()')()
复制代码
再将字符串拼接操作改为ES6的模板字符串形式:
  1. ($ = () => `($ = ${$})()`)()
复制代码
最后去掉空格,得到如下代码。
  1. ($=()=>`($=${$})()`)()
复制代码
这就是史上最短的javascript quine了。需要注意的是,上面的代码需要在浏览器的控制台中运行,如果在IDE中运行,代码格式化工具可能会将代码格式化,导致结果不正确。
你还能想到其他办法吗?欢迎在评论区分享你的想法。
出处:http://www.cnblogs.com/graphics/本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.
来源:豆瓜网用户自行投稿发布,如果侵权,请联系站长删除

相关推荐

您需要登录后才可以回帖 登录 | 立即注册