Javascript代理:修改数组目标和更新数组(长度,内容)

Javascript Proxy: Modify array target and update array (length, content)

本文关键字:数组 长度 内容 更新 代理 修改 目标 Javascript      更新时间:2023-09-26

我正在代理一个数组并根据一些条件修改该数组以保持数据完整性,但是当从代理修改该数组时,该数组不适合放置。

我正在经历的问题是代理数组被***未定义的***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;
  }
});