我正在使用一个带有陷阱的Proxy
对象来跟踪对象键,以便可以轻松地迭代或从对象中选择随机键而不会产生太多性能开销。目前,我将键存储在数组中,因为它们被添加了。这对于插入和随机选择非常有效,但当属性被删除时,开销很大:
// Benchmark
var testObject = createProxy();
var start = performance.now();
for( var i = 0; i < 1e4; i++ )
testObject[Math.random() * 1e6 << 0] = true;
for( var i in testObject )
if( i[0] !== '_' )
delete testObject[ i ];
var end = performance.now();
var total = ( end - start );
console.log( 'Test took ' + total + ' ms' );
// Implementation
function createProxy() {
function keyTracker() {
const set = new Set();
function defineProperty( target, property, descriptor ) {
target[property] = descriptor.value;
if( property[0] === '_' ) return true;
if( set.has( property ) ) return true;
set.add( property );
target[ '__keys' ].push( property );
return true;
}
function deleteProperty( target, property ) {
if( property[ 0 ] === '_' ) return true;
delete target[ property ];
if( !set.delete( property ) ) return true;
target[ '__keys' ] = target[ '__keys' ].filter(
key => key !== property
);
return true;
}
return { defineProperty, deleteProperty };
}
var proxy = new Proxy(
Object.defineProperty( {}, '__keys', {
configurable: true,
enumerable: false,
writable: true,
value: []
} ), keyTracker() );
return proxy;
}
当对象中的键数增加时,调用Array.filter()
变得成倍地费时。我正在寻求一种解决方案,可以避免调用它以删除单个元素。
是否有一种方法可以重新设计它,以实现O(1)插入、随机选择和删除键?