不同编程语言的集合框架差异为何如此巨大?


Author: Kimmy

不同编程语言的集合框架差异为何如此巨大?

知乎链接


真要拿JS的Object和Lua的table来当集合用的话就上当了。
一个很简单的例子,你按F12打开Console(Chrome)就能试验一下:

var obj = {};
obj["[object Console]"] = 1;
obj[console]; // => 1
// console.toString() => "[object Console]"

而对于键值映射来说,上面的显然不能够令人满意(console和"[object Console]"是完全不同的两个东西)。所以ES 6里面专门加入了Map这种东西来填补需要,至少不会再出现像利用对象toString来做索引的情况了。

其实说起来就是,动态语言里面Object / table甚至是其他的那些,都只是为他们本身的对象模型服务的。而也就是因为这一点,才能够让他们做到运行时Reflection。
但是对于集合来说,重要的是数据和数据间的关系,当然你用object / table来实现也没啥,但是就像你想要去对整个集合的元素作一个整体的操作的时候,不借助一些辅助的手段或者黑魔法的话怎么都感觉很蛋疼(谁知道你想要枚举哪些东西呢?不像人家Array那样在ES5就把map / reduce / filter都完善了。

所以,结论就出来了。数据结构单是一个概念,对象模型单是一个概念,而集合框架又是另外一个东西(参考)。虽然后两者在本质上都是所谓的“数据结构”,但是绝对不能混淆。于是后来ES 6机智的把Map给加到核心语言去了。

至于集合框架究竟有多重要,建议题主去试着思考一下怎么把静态类型语言给扩展个具有JS这种灵活的object特性的东西出来,或者试试用C语言做做Web编程,没多久之后题主自己就会发明一个Map了。

## Oct. / 06 / 2014 ##

不太明白,object底层不是用Map实现的?object和Map的区别除了它只用字符串做键之外还有什么?你说到object对于元素操作的不足,那么我是否可以理解成,弥补了这些不足之后object是否就足以实现大部分集合框架的功能了?谢谢。

没错object就是Property的Collection(ECMA-262 $8.6),还准备了两个长相不错的Property Accessor($11.2.1)和一些内部方法($8.6.2)。但是请注意作为集合框架中的Data-Relation和对象模型中Object-Property之间的重要区别:不是说用了[](Property Accessor之一)就一定是要按照指定的key去索引想要的数据。JS既然一不小心把它也做成了对象模型的重要组成部分,那么就要遵守特定的契约(或者是付出相应的代价,比如没事不要做obj["toString"] = null)。

v大说的很对,很多时候就是觉着你们看起来没必要的东西就不该存在,所以就费解它所存在的意义。如果真的把object做成了完全跟Map一模一样了,那么JS就做成了Java了。

另附代码一套:
Object["prototype"]["toString"] = null;
var obj = {};
obj[obj] = 1;   // !=> TypeError

this["obj"]; // => Object {}

(未完待续。

创建时间:2014-10-04 最近更新时间:2023-11-03