- 原文地址:What's the longest keyword sequence in Javascript?
- 原文做者:Leo Horie
- 译文出自:掘金翻译计划
- 本文永久连接:github.com/xitu/gold-m…
- 译者:xionglong58
- 校对者:Endone, Jingyuan0000
最近有几个关于使用 Javascript 编写最长关键字序列的挑战。前端
但问题是:android
让咱们试试能不能作的更好。ios
(可是咱们首先要回顾一些基础规则)git
@arjunb_msft 提出的最长 15 个关键字的程序github
function *f() {
if (1);
else do return yield delete true instanceof typeof void new class extends false in this {}; while (1)
}
复制代码
不幸的是,他的方法里使用了保留字 true
和 false
,而二者实际上不是关键字。在 Chrome 中运行程序也会抛出一个错误:“Uncaught SyntaxError: Unexpected token in”。编程
@bluepnume 提出 15 个关键字的方案是:后端
async function* foo() {
return yield delete void await null in this instanceof typeof new class extends async function () {} {}
}
复制代码
这段程序能够在 Chrome 中运行,可是程序中使用了 null
,这也不是一个关键字。async
虽然有些卖弄,若是咱们从第二个解决方案中剔除 null
,并结合第一个解决方案,能够获得一个不一样的 15 个关键字长度的解决方案:编程语言
async function* foo() {
if (0);
else do return yield delete void await this instanceof typeof new class extends async function () {} {}; while (0)
}
复制代码
哦耶!oop
虽然这样作没什么意思,但卖弄知识却颇有趣。
但不用担忧,由于在下面的讨论中 Bterlson 做了这样的补充:
this
、null
和undefined
能够认为是关键字,即便它们在技术上不是关键字。这使得比赛更有趣(加上编辑们把它们标记成关键字,因此这么说也行得通)
从技术层面讲,this
其实是一个关键字。可是,Bterlson 对 null
和 undefined
不是关键字的认定倒是正确的。
在余下部分,咱们能够看到 true
和 false
也被看成关键字使用。这就给咱们带来了一个问题:若是可使用非关键字标记,那么对于这个挑战,哪些标记更合适?
null
、true
和 false
的共同点是它们都是只包含字母的字面量(显然,包含字符和数字的字面量是不容许的)。
因为可使用 null 字符和 boolean 字符,咱们能够轻松地复现出先前的序列,并构建 17 个单词长度的序列:
async function* foo() {
if (0);
else do return yield await delete void typeof null instanceof this in new class extends async function () {} {}; while (0);
}
复制代码
那 undefined
呢?它其实是一个标识符。若是容许 ASI,那咱们就可使用任意标识符去构造一个无限序列,但这就索然无味了,也失去了挑战的乐趣。
a
b
c
// boooring
复制代码
我倒认为这项挑战的意义在于仅使用相似关键字的标记完成挑战(即便这些相似关键字的词在技术层面不能算做规范的关键字)。
下面是一些看起来像关键字但实际上不是关键字的标记:
let x
for (foo of bar) {}
class { static foo() {} }
import {foo as bar} from 'baz'
{get foo() {}, set foo() {}}
复制代码
若是你不喜欢仔细研究编程语言诸多的规范,并且不能一眼看出哪些标记是关键字,哪些不是关键字,那么下面的标记均可以看成是关键字:let
、of
、static
、as
、from
、get
、set
。它们看起来也确实像关键字。
咱们可能认为不能够往上面的列表中添加 NaN
和 Infinity
之类的东西,是由于它们与 undefined
属于同一个类型,都是标识符(标识符老是指向相同的值),也多是因为只容许使用小写字符。无论怎样,咱们将它们排除在外。咱们也应该排除 atguments
,由于在语法规范中它没有做为标记出现,所以它实际上只是一个 magic 变量,而不是关键字。
另外一个咱们须要排除是 new.target
,由于它中间有一个“.”。
一些标记例如 enum
和 public
是保留字,它们看起来很是像关键字,特别是若是你熟悉像 Java 这样的语言。问题是,它们在语法中几乎到处都会自动变成语法错误,因此即便咱们容许使用它们,也不能真正地使用它们...
// the party poopers
let enum // SyntaxError
interface Bar {} // SyntaxError
package Baz; // SyntaxError
class {
private foo() {} // SyntaxError
}
复制代码
既然咱们已经理清了规则,咱们接下来能作什么呢?
固然有不少啦
因为一向的向后兼容性问题,在某些状况下,许多“关键字” 充当...呃,不能称它们为关键词。咱们以前说过滥用 ASI 和标识符很无聊,但你知道吗?在 Javascript 他们倒是有效的语法。
var undefined
typeof let
复制代码
这固然不是无聊的,并且很是有但愿,因此以娱乐的名义,咱们必须容许它。
最后还有一个小细节要谈。虽然上面的代码片断颇有趣,并且让人眼花缭乱,但它有一个问题:它跨越了两行。很不幸,但咱们须要 ASI 将这两个语句分开,因此咱们没法将它们放在同一行。
或者这样作:
输入一个段落分隔符(\u2029
),若是正确呈现,它看起来以下:
什么都看不见?这就对了!这是一个隐形变量。
如今,有了上面的知识储备,咱们能够提出本身的解决方案:
async function* foo() {
from: set: while (0) {
if (0)
throw as
else this
null
continue from
false
break set
true
var let
debugger
do return yield await delete void typeof get instanceof static in new class of extends async function undefined () {} {}; while (0);
}
}
复制代码
你没看错,这就是在 Chrome 上解析和运行有效的 Javascript 程序。这但是在一行中有 32 个关键字的序列!
固然,并非全部 32 个词都是关键字,这多是 ASI 有史以来最严重的滥用,可是,这仍然有挑战意义。另外,我很开心,这才是最重要的!
那么,你以为呢?你能作一个更长的序列吗?你能弄明白为何这在语法上是有效的吗?这是做弊吗?Gists [译者注:原文发布在 gist 上]是有史以来最被滥用的博客平台吗?
若是发现译文存在错误或其余须要改进的地方,欢迎到 掘金翻译计划 对译文进行修改并 PR,也可得到相应奖励积分。文章开头的 本文永久连接 即为本文在 GitHub 上的 MarkDown 连接。
掘金翻译计划 是一个翻译优质互联网技术文章的社区,文章来源为 掘金 上的英文分享文章。内容覆盖 Android、iOS、前端、后端、区块链、产品、设计、人工智能等领域,想要查看更多优质译文请持续关注 掘金翻译计划、官方微博、知乎专栏。