我正在代理一个数组并根据一些条件修改该数组以保持数据完整性,但是当从代理修改该数组时,该数组不适合放置。
我正在经历的问题是代理数组被***未定义的***s污染。
如何更新目标对象是正确的,如果它被修改?
下面是一个示例笔:http://codepen.io/anon/pen/ZOPLZg(如果您查看控制台,null实际上是未定义的值)。
Chrome版本51.0.2704.103(64位)
var test = new Proxy([], {
set: function(target, name, value, receiver) {
if(name != 'length'){
console.log(name, target)
// I want to overwrite values
var i = target.indexOf(value)
if(i > -1){
// doesn't work
target.splice(parseInt(name, 10), 1);
// doesn't work
delete target[name];
target[i] = value;
}else{
target[name] = value;
}
}else{
target[name] = value;
}
console.log(target);
return true;
}
});
function log(){
$('.log').append('<br/>' + JSON.stringify(test) + test.length);
}
log();
test.push('what', 'hi', 'yo');
log();
test.push('what', 'yo');
log();
test.splice(0, test.length)
log();
在这里提交bug https://bugs.chromium.org/p/chromium/issues/detail?id=638414
if (name != 'length')
{
// ...
} else {
// Your trouble is the next line. Comment it to test
// But i don't understand why.
target[name] = value;
}
你的问题来自于Array.prototype.push自己设置了length属性(参见步骤9),而你的set函数将length属性的赋值作为普通赋值处理。
一种可能的解决方案是只允许对length进行赋值,如果它们不会使数组超过最后一个元素:
var test = new Proxy([], {
set: function(target, name, value, receiver) {
if(name != 'length'){
// I want to overwrite values
if((i = target.indexOf(value)) > -1){
target[i] = value;
}else{
target[name] = value;
}
}else{
if ( value <= Math.max( -1, ... Object.keys( target ) ) + 1 )
target.length = value;
numSkipped = 0;
}
return true;
}
});