admin管理员组文章数量:1323035
I was looking around online and I saw someone do something similar, Array.prototype.push
was proxied and every push was handled, I want to do something like this:
new Proxy(Array.prototype.push, handler);
const array = [];
array.push("e"); // logs "e" to the console somehow from the handler
How can this be achieved?
I was looking around online and I saw someone do something similar, Array.prototype.push
was proxied and every push was handled, I want to do something like this:
new Proxy(Array.prototype.push, handler);
const array = [];
array.push("e"); // logs "e" to the console somehow from the handler
How can this be achieved?
Share Improve this question edited Mar 1, 2023 at 14:50 Sebastian Kaczmarek 8,5154 gold badges24 silver badges43 bronze badges asked Mar 1, 2023 at 14:49 breadbread 1902 silver badges11 bronze badges 6- 1 Are you sure you need to use a proxy?, are you wanting everywhere you you create an array and call push you get logged, if so you just override the prototype, ps. Be careful doing this though, altering prototypes is a little bit frowned on. – Keith Commented Mar 1, 2023 at 14:56
- 1 This sounds like an XY problem. What do you want to achieve which requires proxying a built-in method? – VLAZ Commented Mar 1, 2023 at 14:56
- @VLAZ I'm making a script that needs to be injected into a website, I'm trying to access an object that has certain attributes, I'm trying to proxy Array.push so I can do checks on each push and see if the push was done on the object I'm looking for, and if it was, save the object. – bread Commented Mar 1, 2023 at 14:58
- 1 You can't use a proxy to intercept existing arrays, proxies work by wrapping an existing object and then all access is done via the proxy. Like I mentioned in first ment you can override the array protototype, but be very very careful when doing this. – Keith Commented Mar 1, 2023 at 15:00
- 1 @Keith is right. The only way to somehow get things to work as described is to overwrite the built-in global array. Which is usually to be avoided. Even if you were to modify it, at that point it wouldn't matter whether you used a proxy or not as you're already intrusively changing the built-in global. Proxies are transparent only when you get a chance to hand over a proxy instead of the object. Then it's the same to the consumer. But making sure all consumers use a proxy of an object you don't control is not that. And when built-ins are involved you best thread carefully. – VLAZ Commented Mar 1, 2023 at 15:05
4 Answers
Reset to default 5This will work:
const handler = {
apply(target, thisArg, argumentsList) {
console.log(`called push with argument:', ${argumentsList}`);
return Reflect.apply(target, thisArg, argumentsList)
}
};
Array.prototype.push = new Proxy(Array.prototype.push, handler);
const a = []
a.push(1)
More info:
MDN article about Proxy
handler.apply
But it can break things so be careful
You need to proxy the array and call methods from the proxy.
// Based on:
// - https://stackoverflow./a/35610685/1762224
// - https://stackoverflow./a/47911346/1762224
const
arr = [],
traceMethods = ['push', 'unshift'],
proxiedArr = new Proxy(arr, {
get(target, prop, receiver) {
if (traceMethods.includes(prop)) {
return function(item) {
console.log(`${prop}ing ${item}`);
return target[prop](...arguments);
}
}
return target[prop];
},
});
proxiedArr.push('e'); // logs 'pushing e' to the console
proxiedArr.unshift('f'); // logs 'unshifting f' to the console
console.log(arr); // ["f", "e"]
.as-console-wrapper { top: 0; max-height: 100% !important; }
Capturing push
method on all arrays on a webpage can easily be done by overriding the prototype method.
But, a big warning, doing this could potentially cause side effect. In fact a long time ago in Javascript land they used to be a lib called prototype that actually did this, and got a lot of flack for doing it.
Saying that, there is one area were overriding built-in is remended, and that's pollyfilling new ES features.
If all your wanting to do is log
into the console, maybe for debugging purposes, then your maybe OK.
So with all the warnings out the way, here is an example.
//keep a reference to the old push method
const oldPush = Array.prototype.push;
//now implement our replacement.
Array.prototype.push = function (...args) {
console.log(...args);
return oldPush.call(this, ...args);
}
//lets test.
const a = []
a.push(1)
a.push(1,2,3);
a.push('hello','there');
Of course, you could also do this without the Proxy
for a solution that doesn't change how Arrays work for the rest of the code (which can produce the kind of issue that is hard to troubleshoot):
function push (arr, ...args) {
console.log('Pushed called with', ...args)
arr.push(...args)
}
const arr = []
push(arr, 1)
console.log('arr', arr)
本文标签: javascriptProxy quotArrayprototypepushquotStack Overflow
版权声明:本文标题:javascript - Proxy "Array.prototype.push" - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742108347a2421127.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论