我正在尝试创建javascript的Array的子类。我想用array-type参数启动子类,并添加一个方法从数组(子类)中删除一个元素。
我的代码如下所示:
class CustomArray extends Array {
constructor(array) {
console.log('Initiating array:', array)
super(...array);
}
remove(element) {
let index = this.indexOf(element);
if (index > -1) {
return this.splice(index, 1);
}
return [];
}
}
var a = ['a', 'b', 'c', 'd', 'e'];
var list = new CustomArray(a)
console.log('list:', list);
console.log('remove:', list.remove('c'));
console.log('list:', list);
问题在于,当我调用.splice()时,它会从数组中删除元素,但也会返回已删除元素的数组,实际上它会返回我的子类CustomArray的新实例,该实例应该使用数组类型的参数启动,但是.splice()使用整数类型的参数启动它。
以下是我打电话给.splice()时的想法:
假设我们使用参数list
启动了CustomArray
类的实例['a','b','c','d','e']
,然后我们调用方法list.remove('c')
。 (就像在代码片段中一样)
remove
类的方法CustomArray
检查c
的索引是否在数组['a','b','c','d','e']
中,2
然后调用应删除1的method this.splice(2,1)
数组['a','b','c','d','e']
中索引2处的元素。方法splice
删除元素c
表单数组,但也返回类似new CustomArray(1)
的内容,因为一个元素已从数组中删除,因此它尝试创建长度为1的数组,但由于类{{ 1}}是expectiong数组。
我想阻止CustomArray
方法启动splice
类的新实例,而是返回普通数组(Array对象的实例)。
答案 0 :(得分:1)
我想阻止
splice
方法启动CostomArray
类的新实例,而是返回普通数组(Array
对象的实例)。
然后,您需要使用不同的名称创建不同的方法。 splice
的语义为clearly and precisely defined;他们形成了Array
类型的合同。让CostomArray
违反合同意味着它不再是Array
,而是类似,并且不应该延伸Array
。
由于您的方法被称为remove
,这很好;如果您希望remove
返回Array
,而不是CostomArray
,则只需要自己实施逻辑:
remove(element) {
let index = this.indexOf(element);
if (index > -1) {
const newLength = this.length - 1;
while (index < newLength) {
this[index] = this[index + 1];
++index;
}
this.length = newLength;
return [element];
}
return [];
}
当然,当使用各种CostomArray
方法调用时,使Array.prototype
的构造函数正常工作。 (你在问题中的那个工作得很好,除了记录你不希望console.log
的东西。)
答案 1 :(得分:0)
有可能splice
返回一个标准数组-因此不用它调用构造函数。通过更改自定义类的@@species
property,可以确定将使用哪个构造函数。但是请注意,这不仅会影响splice
,还会影响会创建新实例的所有其他方法,包括map
,filter
,{{1 }},...
您可以通过覆盖相应的静态getter来更改slice
属性:
@@species