为什么是“你好,世界!” JavaScript 代码片段被识别为可接受的程序指令?

xbo*_*und 155 javascript node.js

最近一位同事展示了这段 JavaScript 代码:

greet = "?".toString.bind("hello world!")
Run Code Online (Sandbox Code Playgroud)

如果您将其粘贴到开发者控制台中并执行,它将打印“Hello, World!” 信息:

>> console.log(greet())
hello, world!
Run Code Online (Sandbox Code Playgroud)

我发现的另一个有趣的事情是,如果您将相同的greet代码粘贴到Node.js REPL 中,它会自动将其转换为“可读”格式。

这是如何运作的?为什么这种行为在浏览器中是可能的,为什么 Node.js 会自动格式化它?

dec*_*eze 176

实际代码是:

greet = "...".toString.bind("hello world!")
Run Code Online (Sandbox Code Playgroud)

其中...字符串文字中的 是 bytes E2 80 AE,它是从右到左覆盖的 Unicode 字符,这会导致其后的所有内容反向显示。它用于编写从右到左的语言,如阿拉伯语或希伯来语。

十六进制编辑器是你的朋友

  • RTL 覆盖_不_用于编写从右到左的语言。这些会自动渲染 RTL。更大的问题是数字等共享字符。对于这些,渲染器必须根据上下文来_猜测_ LTR 与 RTL。开发人员插入 RTL 覆盖字符以强制渲染器以所需方向渲染中性方向字符。 (46认同)
  • 这些字符是否也会改变我的浏览器选择双击时突出显示的方式?当我尝试双击 OP 的字符串时,它会突出显示开始引号、结束点和结束引号,中间没有任何内容。有趣的。 (14认同)
  • @Jordan.JD 是的,他们应该在大多数正确处理 RTL 文本的软件中适当地更改选择。 (11认同)
  • @Moo它*在某些情况下编写RTL语言的上下文中使用。*我不想讨论太多细节,因为它与这个问题无关。 (6认同)
  • 请注意,如果您需要此字符作为 BIDI 文本,并且不是故意让您的 JS 代码看起来混乱,那么您可以将其写为“\u202e”。 (2认同)

fee*_*edy 76

您有反转文本的隐藏字符。在这里你可以看到原始字符:https : //www.soscisurvey.de/tools/view-chars.php

在此处输入图片说明

  • 如果我理解你的意思,基本的答案是,这与 Javascript 无关,只是 Unicode 文本渲染顺序,而选择在这里使用 Javascript 是为了转移注意力吗? (30认同)
  • @JaminGrey 显然是这样。我怀疑您可以在 Python 或 Ruby REPL 或许多其他语言中执行相同的操作。这里唯一的 JavaScript 技巧是使用“.bind”从“toString”创建绑定函数。这可以很容易地用“<reversing unicode>”,console.log(“hello world”)`之类的东西代替,你仍然会得到看起来很奇怪但可执行的代码。 (4认同)
  • @JaminGrey 我认为它与开发者控制台的关系比与 Javascript 的关系更大。Ruby 和 Python 控制台只是将 `"\u202E"` 显示为空字符,并且不改变输入的方向,因此 `"hello world!"` 在输入和输出中都按原样显示。根据您的文本编辑器,可能会从右到左编写脚本以获得所需的效果。这是一个 [Ruby 示例](https://tio.run/##KypNqvz/P70oNbVEwVZB165a6VHDutSMnByF/PzynCLFFCW94tIkDX09fR11dU29dDBHQ08TiIAiMUYxhuqatdYFpSXFGmBD9DQ0Nf//BwA)。 (2认同)