我在自动生成的javascript文件中看到了这个:
function map(x){
x={x:x};
delete x.x;
return x
}
我的结论是用于创建对象,但为什么以这种方式创建?这是一种模式吗?
更新
更多信息,创建此代码的工具是来自Google的dart2js,代码在此上下文中使用:
(function (reflectionData) {
function map(x){x={x:x};delete x.x;return x}
if (!init.libraries) init.libraries = [];
if (!init.mangledNames) init.mangledNames = map();
if (!init.mangledGlobalNames) init.mangledGlobalNames = map();
if (!init.statics) init.statics = map();
if (!init.interfaces) init.interfaces = map();
答案 0 :(得分:11)
在dart源代码中,有一条评论说该技术用于v8性能原因:
// [map] returns an object literal that V8 shouldn't try to optimize with a
// hidden class. This prevents a potential performance problem where V8 tries
// to build a hidden class for an object used as a hashMap.
此处的map
一词指的是associative array
答案 1 :(得分:10)
我不久前读过一篇关于此内容的文章,显然如果您delete
来自某个对象, V8 会将该对象置于字典模式或< strong>慢速模式,然后属性存储在“哈希表”中。
V8可以很好地处理这样的小分歧,但是如果你的代码以相同的顺序为同一个构造函数中的对象分配各种随机属性,或者你删除属性,V8会将对象放入字典模式,其中属性存储在哈希表中。这可以防止分配荒谬的地图数量。
这篇文章是http://www.jayconrod.com/posts/52/a-tour-of-v8-object-representation,它与其他内容一起解释。
我可能错了,但我认为这用于大型(大小和生命)对象,以提高性能并减少内存泄漏的可能性。
这与主题相同
Does using delete keyword effect v8 optimizations of an object?
答案 2 :(得分:9)
map
函数的目的是创建一个关联映射对象,其属性集可以快速更改。
自然问题是:默认情况下并非所有JavaScript对象都已经映射过了吗?是的,它们是! EMCAScript规范允许对象随时添加或删除属性,允许它们作为关联映射运行。
但是,唉,负责实现JavaScript执行环境(可能是C ++)的低级语言并不那么容易。特别是,V8使用一个名为hidden classes的概念,其中向JavaScript对象添加属性将导致创建新的C ++类。 V8将此作为优化,因为它假定您的代码将重复使用一小组对象类型。
例如,您的Bullet
类型包含x
,y
,dx
和dy
属性。实际上,这些类型是固定的;您不可能在运行中突然向Bullet
对象添加新属性。隐藏类优化意味着使用一组固定的对象类型运行得非常快,但这也意味着,有时,向JS对象添加新属性的实际成本可能非常高,因为它会提示创建一个具有新属性的新C ++类。
通过在对象delete
上引入x
操作,您向V8引擎发出信号,该对象x
将无法从隐藏类优化中受益。隐藏类背后的想法是,您的对象通常不会更改其属性集(除了在构造时添加新属性)。通过执行delete
,您明确地发出信号表明此对象将以隐藏类完全无益的方式更改其属性集。对于这个对象,创建隐藏类的成本远远超过了好处。
因此,map
返回的对象将被排除在V8隐藏类优化之外,允许它更快地添加和删除任意属性。