I was trying to extend the built-in Array with my own custom getters/methods, and everything was fine until I met the array literal.
The following is my code:
/* ------------------ instance proxy ------------------ */
// extension of Array instances (proxy's handler)
const ArrayInstanceExtension = {
// "get" trap
get: (target, key) => {
switch(key){
/* -------- extensions -------- */
// arr.first
case "first": {
return target[0];
}
// arr.last
case "last": {
return target[target.length - 1];
}
/* -------- built-in -------- */
// original arr.prop/method
default: {
return (typeof target[key] === "function")
? target[key].bind(target) // method ⭐️
: target[key]; // property
}
}
}, // end: get
};
/* ------------------ class extension ------------------ */
// Array "class" extension (proxy's handler)
const ArrayClassExtension = {
// ⭐️ "construct" trap: intercepts `new Array(...args)`
construct: (target, args) => {
return new Proxy( new target(...args) , ArrayInstanceExtension )
// ╰ new Array(...) -╯ ╰- instance handler -╯
}
};
// ⭐️ Array extension (which will shadow the original Array)
// target ↴
// ╭- -╮ ╭--- extension ---╮
Array = new Proxy(Array, ArrayClassExtension);
/* ------------------ test run ------------------ */
// proxied array instance
let a = new Array(0,1,2,3,4);
// ⭐️ My problem is here:
// Array literals are not (automatically) proxied.❗️
let b = [1,2,3];
// unless we do it manually.
// b = new Proxy(b, ArrayInstanceExtension);
[
a.length, // 5
a.last, // 4
a.first, // 0
b.last, // ⭐️ proxied ? 3 : undefined
b.first, // ⭐️ proxied ? 1 : undefined
].forEach(x => console.log(x));
As the above code shows, my problem is that:
when I'm using the new Array(...) syntax, everything's fine, but if I use the array literal syntax, the array won't be proxied automatically, and that is an inconvenience that I wish I could fix.
Is it possible to "intercept" the array literal syntax in any way? Thanks.