我正在尝试代理 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]] 以检查值。
谢谢!
我可以给你以下解决方案:
/* 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