为什么JavaScript中的Sets/Maps使用`size`而不是`length`?

12
当我查看JavaScript的新变化时,我注意到SetMap使用.size而不是像数组一样使用.length
这似乎是与数组的正常用法背道而驰的无意义偏离 - 又多了一件需要记住的事情。
这是否有一个好的设计原因?

1
我的猜测是,集合和映射并不像数组那样被视为具有“长度”的一维向量。你认为将堆或栈的大小命名为除length以外的其他名称是否不好? - Anders Marzi Tornblad
6
这是一个很好的问题,将会回答你的疑问。https://dev59.com/2HVC5IYBdhLWcg3wbQbA - Michael Warner
1
就Set而言,如果您查看规范,与Array的长度相比,主要区别在于每次调用size时都会重新计算大小。现在我不确定这是命名不同的主要原因,实际上我怀疑。 - bug-a-lot
@bug-a-lot 不一定 - 规范中还进一步说明:“此Set对象规范中使用的数据结构仅旨在描述Set对象所需的可观察语义,而不是可行的实现模型。”当添加内容时,可以缓存大小等。 - James Thorpe
@JamesThorpe 是的,这一点并不奇怪。当我写这个答案的时候,我实际上在想,没有一个理智的人会按照规范中所示的方式来实现它。 - bug-a-lot
2个回答

18

在 esdiscuss 论坛主题 "Set length property" 中有很多关于此的讨论。由于这是一个备受争议的问题,你不一定会同意这个解决方案。

在 esdiscuss 中对此进行了大量的争论。最终胜出的观点(正如 ES2015 的 Set 具有 size 而不是 length 所证明的那样)总结在 David Bruant 的帖子中

……对我来说,“length” 是像尺子一样测量长度的东西。您从0开始并查看到它的末尾。对于一个索引集(从0开始增长)和 ECMAScript 数组所受启发的 C 中考虑的数组(连续的字节序列)非常准确。对于无序集合(例如 sets)而言,这可能不太相关,我倾向于将其视为混乱的袋子。

并在 Dean Landolt 的帖子中进一步讨论:

我只是想插一句话,说非可写的 length 也符合 String 的行为,但 David 提出了一个很好的观点,即 length 暗示着度量拓扑。David 建议使用 count 很好。ISTM 我们正在谈论的是基数,但没有必要过于精确。虽然 size 对我来说挺好的,并且有足够的先例。


这确实是这个问题唯一合理的答案。我想知道是否有人考虑过做一个项目,用链接注释规范中讨论的内容... 嗯... - James Thorpe

1
虽然apsillers在2016年1月27日的回答中提供了很好的链接,但缺少代码示例。集合的size是只读的,而数组允许修改length以截断数组。

let arr = [1, 2, 3, 4]
arr.length = 2
console.log("modified length array", arr) // [1, 2]

let mySet = new Set([1, 2, 3, 4])
mySet.length = 2
mySet.size = 2
console.log("modified length set", [...mySet]) // [1, 2, 3, 4]

let str = "1234"
str.length = 2
console.log("modified length string", str) // "1234"


我一直在寻找截断Map的最佳实践,因为当涉及到具有项目集插入顺序和查找的结构时,Maps通常是首选的结构,两者兼备。但据我所知,截断Map的唯一方法是迭代它,与设置数组长度(然后丢弃不再索引的所有内容)相比,这似乎非常慢。但我可以理解为什么可能只是这样/必须是这样。 - Dtipson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接