如何在所有 JavaScript 数组对象上代理 [[set]]?

问题描述 投票:0回答:1

我正在尝试代理 JavaScript 数组上的 [[set]] 方法。是否可以代理所有阵列,而不仅仅是某个特定阵列?我的处理程序将检查数组中设置的对象,如果它

hasOwnProperty('xyz')
,则
console.log
它。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy说 我会用类似的东西来做到这一点

set(target, prop, val) { // to intercept property writing
    if (val.hasOwnProperty('xyz') {
        console.log(prop);
    };
    target[prop] = val;
    return true;
  }

但是,

Proxy
似乎只适用于单个对象。鉴于没有原型 [[set]],我如何为每个数组代理此操作?

理想情况下,它会像这样工作:

Array = new Proxy(Array, {
set(target, prop, val) { // to intercept property writing
    if (val.hasOwnProperty('xyz') {
        console.log(prop);
    };
    target[prop] = val;
    return true;
  }
});

let obj = {xyz: 1}
let list = [];
list[0] = obj; // would log 1

我尝试了上面的代码片段,但它没有为每个数组重新定义方法。一种可能的方法是代理 Array.prototype.constructor 返回一个数组,其中预先代理了 [[set]] 以检查值。

谢谢!

javascript arrays es6-proxy
1个回答
0
投票

我可以给你以下解决方案:

/* Keep `Array` as is. It's better this way. */
function MyHandledArray ()
{
   /* Your proxy should go over your object, not it's prototype. */
   return new Proxy
   (
      /* This just use the `Array` constructor to build a new object. */
      Reflect.construct(Array, arguments, MyHandledArray),
      /* Bellow is the handler that will intercept the new object. */
      {
         set: ( Target, Property, Value ) =>
         {
            if ( Reflect.has(Value, 'xyz') )
            {
               /* You want to log the indexes which contains objects with xyz property? */
               // console.log(Property);
               /* Or you wanted to log the `xyz` property value of the `Value` object? */
               console.log(Value.xyz);
            }
            
            Target[Property] = Value;
            
            return Reflect.has(Target, Property);
         }
      }
   );
}

/* Adjust the function to properly inherit `Array`... */
Reflect.setPrototypeOf(MyHandledArray, Array);
Reflect.setPrototypeOf(MyHandledArray.prototype, Array.prototype);

/* Then, only then, use it. */

var Obj = {xyz: 1};
var Arr = MyHandledArray();

Arr[0] = Obj; // outputs: 1
Arr[1] = {xyz: 2}; // outputs: 2
Arr[3] = {nothing: null}; // outputs nothing
Arr[4] = {xyz: 'Hello', more: 'stuff'}; // outputs: Hello

© www.soinside.com 2019 - 2024. All rights reserved.