javascript - Ruby 和 JavaScript 中的符号是否具有相同的用途?
问题描述
Symbol
从编程语言设计的角度来看,Ruby 和 JavaScript(也许其他一些也具有等效类型的编程语言)是否具有相同的目的?(问题 #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(..)
无论参数是什么,总是返回一个新符号:
// Why this is designed this way? Question #2
Symbol('a') === Symbol('a') // false
解决方案
它们是彼此的对立面。RubySymbol
保证它总是一样的。ECMAScriptSymbol
保证它总是不同的。
RubySymbol
用于表示“名称”或“标签”的Array
概念,其方式与用于表示“一系列事物”的概念或String
用于表示“文本”的概念的方式相同。Ruby 的Symbol
s 通常被描述为“不可变String
的 s”,但实际上Integer
它们与String
s 的距离比与 s 的距离更近。(Integer
s 也是不可变的,也是直接的,也是唯一的,并且Intege
文字也对自己进行评估。)事实上,在早期版本的 Ruby 中,Symbol
s 和Fixnum
s(固定大小Integer
的 s)密切相关,甚至可以转换为每个其他。使Symbol
s 更像String
是一种最近(15 年)的现象。
ECMAScriptSymbol
是不可伪造的令牌。这个概念来自基于能力的安全。Mark Miller 是基于能力的安全性和基于对象能力的安全性方面最重要的研究人员之一,也是 E 基于能力的编程语言的设计师,是推动 ECMAScript 设计(包括 Realms)安全方面的 TC39 委员会成员之一和符号,所以这并不奇怪。
因为 ECMAScriptSymbol
总是不同的,所以你不可能生成一个Symbol
等于 my 的Symbol
. (这就是“不可伪造的令牌”的意思。)所以,如果我使用 aSymbol
来保护对某些东西的访问,我可以 100% 确定没有人可以访问,除非我明确地将“我的”交给他们Symbol
。这Symbol
成为“访问能力”,因此成为“基于能力的安全性”。
如果您想实际重用 a Symbol
,则必须确保明确“记住”它。这就是Symbol.for
为您所做的:它会为您记住Symbol
,并在您要求时将其返回给您。这样,它本质上实现了 Ruby 的语义Symbol
,并且可以这样使用。
另一个例子是“知名Symbols
”,例如Symbol.iterator
. 这只是一个总是返回相同的方法Symbol
——它Symbol
是不透明且不可伪造的,所以你永远无法自己重新创建它。这些方法本质上也只是Symbol
为您“记住”一个特定的。
但这不是Symbol
ECMAScript 中 s 的主要用例。主要用例是基于能力的安全性。(你可以把它想象成一把钥匙,但这也是一个有缺陷的类比,因为钥匙可以被复制,也可以被伪造——Symbol
但不能。)
推荐阅读
- java - 失去连接后 Eclipse Milo 不会重新连接到服务器 - 订阅
- mysql - InnoDB 中 FOR UPDATE 和 START TRANSACTION 的区别
- javascript - 将 Excel 表单数字化为 HTML 表单
- javascript - 我如何使用 ionic 3 在 delete 方法中一起传递 header 和 parmas
- mailto - 单击邮件时如何使用给定的配置文件调用 Thunderbird:链接
- java - PropertySource 在 DispatcherServletInitializer 中不起作用
- c# - ''Microsoft.ACE.OLEDB.12.0' 提供程序未在本地计算机上注册。'
- javascript - 如何添加同步回调以存储在 ExtJS 中
- c# - 线程内核对象是否依赖于 CPU
- buildroot - Buildroot 2020.02 为什么我不能添加 resize2fs 二进制文件?