Ruby 中的符号和 JavaScript 中的符号有相同的用途吗?

azt*_*ack 0 javascript ruby language-design typescript

Symbol从编程语言设计的角度来看,Ruby 和 JavaScript(也许其他一些也具有等效类型的编程语言)是否具有相同的目的?(问题#1)

我知道这两种语言都有Symbol类型。

Symbol在这两种语言中都可以用来从对象中检索方法:

const a = [];
a[Symbol.iterator] // [Function: values]
Run Code Online (Sandbox Code Playgroud)
a = []
a.method(:at) => #<Method: Array#at(_)>
Run Code Online (Sandbox Code Playgroud)

Ruby 中的符号是独一无二的:

:a.object_id => 776028
:a.object_id => 776028
Run Code Online (Sandbox Code Playgroud)

在 JavaScript 中,使用创建的符号Symbol.for保存在内部字典中,这使得它类似于unique

Symbol.for('a') === Symbol.for('a') // true
Run Code Online (Sandbox Code Playgroud)

Symbol(..)无论参数是什么,总是返回一个新符号:

// Why this is designed this way? Question #2
Symbol('a') === Symbol('a') // false
Run Code Online (Sandbox Code Playgroud)

Jör*_*tag 6

他们是彼此对立的。RubySymbol保证它始终是相同的。ECMAScriptSymbol保证它总是不同的

\n

RubySymbol用于表示“名称”或“标签”的概念,就像Array用于表示“事物序列”的概念或String用于表示“文本”的概念一样。Ruby 的Symbols 通常被描述为“不可变的Strings”,但它们实际上更接近于Integers,而不是Strings。(Integers 也是不可变的,也是立即的,也是唯一的,并且Intege文字也计算自身。)事实上,在 Ruby 的早期版本中,Symbols 和Fixnums (固定大小Integers)密切相关,甚至可以转换为每个其他。Symbol使s 变得更像- 的动力String是最近(15 年)才出现的现象。

\n

ECMAScriptSymbol不可伪造的令牌。这个概念来自于基于能力的安全。Mark Miller 是基于能力的安全性和基于对象能力的安全性方面最重要的研究人员之一,也是基于能力的 E 编程语言的设计者,也是推动 ECMAScript 设计(包括 Realms)安全方面的 TC39 委员会成员之一和符号,所以这并不奇怪。

\n

因为 ECMAScriptSymbol总是不同的,所以你不可能生成一个Symbol与我的Symbol. (这就是“不可伪造的令牌”的含义。)因此,如果我使用 aSymbol来保护对某些内容的访问,我可以 100% 确定没有人可以访问,除非我明确地将它们交给“我的” Symbol。这Symbol成为“访问能力”,因此成为“基于能力的安全性”。

\n

如果您想实际重复使用Symbol,则必须确保明确“记住”它。这就是Symbol.for为您做的事情:它会Symbol为您记住,并在您要求时将其返还给您。这样,它本质上实现了 Ruby 的语义Symbol,并且可以这样使用。

\n

另一个例子是“众所周知的Symbols”,例如Symbol.iterator。这只是一个总是返回相同的方法Symbol\xc2\xa0\xe2\x80\x93 的方法,它Symbol是不透明且不可伪造的,因此您永远无法自己重新创建它。这些方法本质上也只是Symbol为您“记住”特定的内容。

\n

但这不是主要用例SymbolECMAScript 中 s 的主要用例。主要用例是基于功能的安全性。(你可以把它想象成一把钥匙,但这也是一个有缺陷的类比,因为钥匙可以被复制,并且它们可以被伪造\xc2\xa0\xe2\x80\x93 Symbols不能。)

\n