Ruby 和 JavaScript 中的符号是否具有相同的用途?
Is symbol in Ruby and JavaScript have the same purpose?
Ruby 和 JavaScript 中的 Symbol
(也许其他一些也具有等效类型的编程语言)从编程语言设计的角度来看具有相同的目的吗? (问题 #1)
我知道这两种语言都有 Symbol
类型。
Symbol
两种语言均可用于从对象中检索方法:
const a = [];
a[Symbol.iterator] // [Function: values]
a = []
a.method(:at) => #<Method: Array#at(_)>
Ruby 中的符号是唯一的:
:a.object_id => 776028
:a.object_id => 776028
在JavaScript中,用Symbol.for
创建的符号保存在一个内部字典中,这使得它有点像unique
:
Symbol.for('a') === Symbol.for('a') // true
但是 Symbol(..)
总是 return 一个新的符号,不管参数是什么:
// Why this is designed this way? Question #2
Symbol('a') === Symbol('a') // false
他们是彼此的对立面。 Ruby 的 Symbol
保证它 始终相同 。 ECMAScript 的 Symbol
保证它总是不同的。
Ruby的Symbol
用来表示“名称”或“标签”的概念,与Array
用来表示的概念相同“a sequence of things”或String
用来表示“文本”的概念。 Ruby 的 Symbol
通常被描述为“不可变的 String
”,但实际上它们更接近 Integer
而不是 String
. (Integer
也是不可变的,也是直接的,也是唯一的,并且 Intege
字面量也对它们自己求值。)事实上,在 Ruby 的早期版本中,Symbol
s 和 Fixnum
s(固定大小 Integer
s)密切相关,甚至可以相互转换。让 Symbol
更像 String
的动力是最近(15 年)的现象。
ECMAScript 的 Symbol
是一个 不可伪造的令牌 。这个概念来自基于能力的安全。 Mark Miller 是基于能力的安全性和基于对象能力的安全性领域最重要的研究人员之一,也是基于 E 能力的编程语言的设计者,也是推动 ECMAScript 设计安全方面(包括领域)的 TC39 委员会成员之一和符号,所以这并不奇怪。
因为 ECMAScript Symbol
总是不同的,所以 不可能 你生成一个 Symbol
等于我的 Symbol
. (这就是“不可伪造的令牌”的意思。)所以,如果我使用 Symbol
来保护对某些东西的访问,我可以 100% 确定 没有人 可以访问,除非我明确地把“我的”交给了他们Symbol
。 Symbol
成为“访问能力”,因此成为“基于能力的安全性”。
如果您想真正重复使用 Symbol
,您必须确保明确地“记住”它。这就是 Symbol.for
为您所做的:它会为您记住 Symbol
,并在您需要时将其还给您。这样,它基本上实现了 Ruby 的 Symbol
的语义,并且可以那样使用。
又如“家喻户晓的Symbols
”,如Symbol.iterator
。这只是一个始终 returns 相同 Symbol
的方法 – Symbol
是不透明且不可伪造的,因此您永远无法自己重新创建它。这些方法本质上也只是为您“记住”特定的 Symbol
。
但这不是 ECMAScript 中 Symbol
s 的主要用例。主要用例是基于功能的安全性。 (你可以把它想象成一把钥匙,但这也是一个有缺陷的类比,因为钥匙可以被复制,而且它们可以被伪造——Symbol
s 不能。)
Ruby 和 JavaScript 中的 Symbol
(也许其他一些也具有等效类型的编程语言)从编程语言设计的角度来看具有相同的目的吗? (问题 #1)
我知道这两种语言都有 Symbol
类型。
Symbol
两种语言均可用于从对象中检索方法:
const a = [];
a[Symbol.iterator] // [Function: values]
a = []
a.method(:at) => #<Method: Array#at(_)>
Ruby 中的符号是唯一的:
:a.object_id => 776028
:a.object_id => 776028
在JavaScript中,用Symbol.for
创建的符号保存在一个内部字典中,这使得它有点像unique
:
Symbol.for('a') === Symbol.for('a') // true
但是 Symbol(..)
总是 return 一个新的符号,不管参数是什么:
// Why this is designed this way? Question #2
Symbol('a') === Symbol('a') // false
他们是彼此的对立面。 Ruby 的 Symbol
保证它 始终相同 。 ECMAScript 的 Symbol
保证它总是不同的。
Ruby的Symbol
用来表示“名称”或“标签”的概念,与Array
用来表示的概念相同“a sequence of things”或String
用来表示“文本”的概念。 Ruby 的 Symbol
通常被描述为“不可变的 String
”,但实际上它们更接近 Integer
而不是 String
. (Integer
也是不可变的,也是直接的,也是唯一的,并且 Intege
字面量也对它们自己求值。)事实上,在 Ruby 的早期版本中,Symbol
s 和 Fixnum
s(固定大小 Integer
s)密切相关,甚至可以相互转换。让 Symbol
更像 String
的动力是最近(15 年)的现象。
ECMAScript 的 Symbol
是一个 不可伪造的令牌 。这个概念来自基于能力的安全。 Mark Miller 是基于能力的安全性和基于对象能力的安全性领域最重要的研究人员之一,也是基于 E 能力的编程语言的设计者,也是推动 ECMAScript 设计安全方面(包括领域)的 TC39 委员会成员之一和符号,所以这并不奇怪。
因为 ECMAScript Symbol
总是不同的,所以 不可能 你生成一个 Symbol
等于我的 Symbol
. (这就是“不可伪造的令牌”的意思。)所以,如果我使用 Symbol
来保护对某些东西的访问,我可以 100% 确定 没有人 可以访问,除非我明确地把“我的”交给了他们Symbol
。 Symbol
成为“访问能力”,因此成为“基于能力的安全性”。
如果您想真正重复使用 Symbol
,您必须确保明确地“记住”它。这就是 Symbol.for
为您所做的:它会为您记住 Symbol
,并在您需要时将其还给您。这样,它基本上实现了 Ruby 的 Symbol
的语义,并且可以那样使用。
又如“家喻户晓的Symbols
”,如Symbol.iterator
。这只是一个始终 returns 相同 Symbol
的方法 – Symbol
是不透明且不可伪造的,因此您永远无法自己重新创建它。这些方法本质上也只是为您“记住”特定的 Symbol
。
但这不是 ECMAScript 中 Symbol
s 的主要用例。主要用例是基于功能的安全性。 (你可以把它想象成一把钥匙,但这也是一个有缺陷的类比,因为钥匙可以被复制,而且它们可以被伪造——Symbol
s 不能。)