介绍

如何写一段javascript程序,输出自身的源代码?这个问题非常有意思,大家不妨先尝试一下,反正在尝试了半个小时之后,我果断放弃了。

这种能输出自身的程序在英文里被称为quine

准备知识

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

  1. IIFE
  2. toString()方法

关于IIFE,之前的文章已经做过详细的介绍,这里就不再赘述了,感兴趣的同学可以先去看一下。

JavaScript IIFE揭秘

关于toString()方法,相信大家也不陌生,但是你可知道对于一个函数来说,调用toString()方法意味着什么?

没错,调用一个函数的toString()方法会返回这个函数的源代码。

function foo() {
console.log('hello world')
} console.log(foo.toString()) // 输出foo的源代码

第一个例子

有了上面的知识储备,我们可以动手写一下了,首先写一个函数foo,在函数体内调用console.log(foo.toString())输出函数的源代码。

function foo() {
console.log(foo.toString())
}

但是这只是函数定义,并未执行,所以需要在函数定义之后调用它。

function foo() {
console.log(foo.toString())
}
foo() // 调用函数,输出源代码

运行上面的代码,输出的结果如下所示,可以看到最后的调用语句foo()并没有打印出来。

function foo() {
console.log(foo.toString())
}

这不符合我们的要求,所以考虑去掉调用语句,将函数改为IIFE的形式

(function foo() {
console.log(foo.toString())
})()

运行上面的代码,输出的结果如下,最外层的()和末尾调用函数的()没有打印出来,这也不符合我们的要求。

function foo() {
console.log(foo.toString())
}

改造一下内部的console.log,将两组括弧也输出来。

(function foo() {
console.log('(' + foo.toString() + ')()')
})()

这回结果终于正确了,我们进一步改造,使用+拼接字符串时,js会自动将+另一侧的操作数转换为字符串,所以我们可以把toString()省略掉。

(function foo() {
console.log('(' + foo + ')()')
})()

再增加点神秘感,将foo换成$

(function $() {
console.log('(' + $ + ')()')
})()

运行结果如下:

(function $() {
console.log('(' + $ + ')()')
})()

这就是一个简单的javascript quine了。

最短的例子

在上面的例子中,为了便于观察结果,使用了console.log输出了源代码,实际上我们可以直接返回源代码,这样就可以省略掉console.log语句。

(function $() {
return '(' + $ + ')()'
})()

根据前面两篇文章学到的IIFE的知识,我们使用IIFE的箭头函数形式。下面这段代码定义一个箭头函数并将其赋值给变量$,然后立即执行这个函数。

($ = () => {
return '(' + $ + ')()'
})()

但是它的执行结果中没有包含$,我们加上$

($ = () => {
return '($ =' + $ + ')()'
})()

根据箭头函数的规则,如果返回值只有一行,那么可以省略掉大括号{}return关键字,所以我们可以进一步简化为

($ = () => '($ =' + $ + ')()')()

再将字符串拼接操作改为ES6的模板字符串形式:

($ = () => `($ = ${$})()`)()

最后去掉空格,得到如下代码。

($=()=>`($=${$})()`)()

这就是史上最短的javascript quine了。需要注意的是,上面的代码需要在浏览器的控制台中运行,如果在IDE中运行,代码格式化工具可能会将代码格式化,导致结果不正确。

你还能想到其他办法吗?欢迎在评论区分享你的想法。

JavaScript Quine揭秘:如何让程序输出自身源代码?的更多相关文章

  1. 创建ArcGIS API for JavaScript的第一个示例程序

    原文:创建ArcGIS API for JavaScript的第一个示例程序 在上一篇博客中已经介绍了如何搭建ArcGIS API for JavaScript开发环境,如果您还没有搭建好开发环境的话 ...

  2. javascript两行代码按指定格式输出日期时间

    javascript两行代码按指定格式输出日期时间,具体看代码: function date2str(x,y) { var z ={y:x.getFullYear(),M:x.getMonth()+1 ...

  3. PHP程序输出日历

    以下代码只是简单实现日历的效果和逻辑思路,没有使用类封装,权当抛砖引玉,有兴趣的朋友可以封装起来,方便调用. <?php /** * PHP利用时间函数输出日历 * Rain.zen $ int ...

  4. Bootstrap3 代码-程序输出

    通过 <samp> 标签来标记程序输出的内容. This text is meant to be treated as sample output from a computer prog ...

  5. java笔记--重定向输出流实现程序输出到日志

    重定向输出流实现程序输出到日志 --如果朋友您想转载本文章请注明转载地址"http://www.cnblogs.com/XHJT/p/3877248.html "谢谢-- 利用Sy ...

  6. 双缓冲解决控制台应用程序输出“闪屏”(C/C++,Windows)

    使用 C 语言编写游戏的小伙伴们想必起初都要遇到这样的问题,在不断清屏输出数据的过程中,控制台中的输出内容会不断地闪屏.出现这个问题的原因是程序对数据处理花掉的时间影响到了数据显示,或许你可以使用局部 ...

  7. 用VSCode终端实现重定向比较程序输出和正确输出

    在刷 OJ 题目或者进行编程考试或比赛时,经常需要对编写好的程序进行测试,即运行编写好的程序,输入样例输入或者自己编写的输入数据,查看程序输出结果和样例输出或者正确输出是否一致.这种方法有很多弊端,当 ...

  8. cmake指定程序输出目录和库文件输出目录和拷贝文件

    概述 本文样式环境: win10+cmake 3.18 本文将介绍使用CMAKE配置项目输出目录和 LIbrary项目的输出目录 本文将介绍 cmake的file函数的基础用法之拷贝文件 重点, 这些 ...

  9. 【转】【译】JavaScript魔法揭秘--探索当前流行框架中部分功能的处理机制

    推荐语: 今天推荐一篇华为同事的同事翻译的一篇文章,推荐的主要原因是作为一个华为员工居然晚上还能写文章,由不得小钗不佩服!!! 其中的jQuery.angular.react皆是十分优秀的框架,各有特 ...

  10. javascript quine

    javascript有一些奇怪的性质,恩,比如说,非常容易写一个quine,即自己输出自己代码的东西. function a(){console.log(a.toString()+";a() ...

随机推荐

  1. sql server2008出现set 选项的设置不正确:"ARITHABORT”

    ( SELECT STUFF(( SELECT '','' + CODE FROM INVNEWSAL11 WHERE (MASTERI=BILRCV.SRCERI) OR (LINKERI IN ( ...

  2. Readers and Writers JSON Framework(2)

    我们关心json的读写.特别在datasnap中,关于使用stream更是显得重要.其实轮子都帮你做好了,你不知道整经再研究就是一个悲哀.除非你要研究. 回正题: 处理json有二套框架. JSON ...

  3. windows下jdk版本切换(bat)

    1.jdk下载 Oracle官网 https://www.oracle.com/cn/ 资源->下载->Java下载 jdk当前最新版本 jdk22版本 jdk8版本 当前页面向下拉 2. ...

  4. 查看MySQL是否安装成功

    1)安装了Windows Service:MySQL80,并且已经启动. 2)安装了MySQL软件.安装位置为:C:\Program Files\MySQL  (默认路径) (MySQL文件下放的是软 ...

  5. Python3_python2打包exe文件

    最近要把绿盟报告导出脚本打包成一个exe,原本是一个py2的文件Vulreport.py,我做了如下步骤. 1.py2topy3 Python3 2to3.py -w Vulreport.py 2.p ...

  6. [设计模式/Java] 设计模式之解释器模式【27】

    概述:解释器模式 := Interpreter Pattern ∈ 行为型模式 模式定义 解释器模式(Interpreter Pattern)提供了评估语言的语法或表达式的方式 属于行为型模式. 解释 ...

  7. 突破Excel百万数据导出瓶颈:全链路优化实战指南

    在日常工作中,Excel数据导出是一个常见的需求. 然而,当数据量较大时,性能和内存问题往往会成为限制导出效率的瓶颈. 当用户点击"导出"按钮时,后台系统往往会陷入三重困境: ‌内 ...

  8. ModelForm验证实例

    程序目录 models.py from django.db import models# Create your models here.class UserType(models.Model):   ...

  9. 将查询集SQL-存为物理 OR 临时表

    最近的BI项目, 就是会涉及大量的 sql, 后台处理也全是 sql 来拼接成一张物理宽表, 然后前台也是用 sql 来做各种图形骚操作. 尤其是后台处理部分, 大量的sql, 有点尴尬的事情是, s ...

  10. C#数据结构及算法之链表

    C# 链表 链表是节点的列表,节点包含两部分:值和链接,其中值部分用于储存数据,链接部分用于指向下一个元素的地址,是引用 类型. 单链表 public class LinkedList { priva ...