3 回答
TA贡献1785条经验 获得超8个赞
我不认为你可以像这样“劫持”所有数组。即使您对本机Array
函数进行猴子修补,使用文字符号 ie 创建的数组也[]
不会受到影响:
console.log(new Array(1,2,3));
console.log([4,5,6]);
Array = function () {
throw new Error;
};
try {
console.log(new Array(1,2,3));
} catch (e) {
console.log('Cannot create array with new Array');
}
console.log([4,5,6]);
正如您可能认为的那样,您需要将数组传递给其他东西。您只需选择适合您的解决方案即可。就我个人而言,我会尝试使用代理:
const spy =
(arr, fn) =>
new Proxy(arr, {
get(target, prop) {
if (prop === "max") {
return Math.max(...target);
}
if (prop === "min") {
return Math.min(...target);
}
if (typeof target[prop] === "function") {
fn();
}
return target[prop];
}
});
const arr = spy([1,2,3], () => console.log('spied'));
arr.push(500);
arr.push(-10);
console.log(arr.min, arr.max, JSON.stringify(arr), Array.isArray(arr));
我喜欢代理的一点是,它可以被设计成不会造成妨碍。上面的例子中arr
仍然是一个数组。您可以做您以前做过的所有正常事情。例如Array.isArray
仍然返回true
并JSON.stringify
仍然产生预期结果。
但是请注意,在上面的实现中,如果您从中生成另一个数组,arr
则不会自动代理:
const arr = spy([1,2,3], fn); arr.slice(1); // [2,3] (non-proxied array!)
TA贡献1796条经验 获得超10个赞
你在这里有正确的想法:
class MyCustomArray extends Array {
constructor(...args) {
super(...args);
console.log('custom array');
}
}
您只需要更改要Array扩展类的类,它应该是Array<T>这样Array的:
class MyCustomArray extends Array<T> {
constructor(...items) {
super(...items);
console.log('custom array');
}
}
这里的<T>T 代表数组中包含的对象的类型,例如,如果它将是一个仅包含数字的数组,那么您可以将<number>.
现在您可以向该数组添加任何功能并使用以下语法创建该数组的实例:
const array = new MyCustomArray(item1, item2...)
希望这可以帮助
TA贡献1942条经验 获得超3个赞
嗯,它有点暴力,但是,Array 有点特殊,因为如果您为扩展类提供构造函数,则其创建新数组的方法将使用该构造函数,因此,例如,myCustomArray.filter
会生成myCustomArray
对象结果而不是一个Array
对象结果。(如果您不提供构造函数,则这不起作用)。
如果我想随时访问该自定义类型中数组的特定自定义功能,我可能会在创建时将值设置为 null,并扩展更改现有对象(如 )的方法以将其设置为 null,然后将其设置为 null pop
。一种方法,该方法可以提供非空缓存值,或者计算、缓存并返回当前值。
我没有仔细计算,但我认为只有少数数组方法可以更改现有数组(而不是创建新数组),因此应该不需要太多努力。
添加回答
举报