在JavaScript的Array子类中使用.splice方法? [英] Using .splice method in subclass of Array in javascript?

查看:121
本文介绍了在JavaScript的Array子类中使用.splice方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建javascript数组的子类.我想使用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():

假设我们有一个CustomArray类的实例list,它是用参数['a','b','c','d','e']初始化的,然后调用方法list.remove('c'). (就像代码段中一样).
CustomArray类的方法remove检查c的索引在数组['a','b','c','d','e']中,该数组是2,然后调用method this.splice(2,1),它应删除数组['a','b','c','d','e']中在索引2处的1个元素.方法splice删除元素c表单数组,但也会返回类似new CustomArray(1)的内容,因为一个元素已从表单数组中删除,因此它尝试创建长度为1的数组,但是失败,因为类CustomArray是期望数组./p>

我想防止splice方法启动CustomArray类的新实例,而是返回普通数组(Array对象的实例).

Jsbin链接.

解决方案

我想防止splice方法启动CostomArray类的新实例,而是返回普通数组(Array对象的实例).

然后,您需要使用不同的名称创建不同的方法. splice的语义是清晰准确地定义;它们构成Array类型的合同.如果您的CostomArray违反了合同,则意味着它不再是Array了,它类似于 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记录不需要的内容外,您在问题中遇到的那个还可以.)

I am trying to create a subclass of javascript's Array. I want to initiate subclass with array-type argument and add a method to remove an element from the array (subclass).

My code looks like this:

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);

The problem is that when I call .splice() it removes element from array, but also returns array of deleted elements, actually it returns new instance of my subclass CustomArray, which should be initiated with argument of array type, but .splice() initiates it with arguments of integer type.

Here is an example of what I think happens when I call .splice():

Let's say we have instance list of CustomArray class initiated with argument ['a','b','c','d','e'] and then we call method list.remove('c'). (Just like in code snippet).
Method remove of CustomArray class checks the index of c is in array ['a','b','c','d','e'], which is 2 and then calls method this.splice(2,1) which should remove 1 element at index 2 in array ['a','b','c','d','e']. Method splice removes element c form array, but also returns something like new CustomArray(1) because one element was removed form array so it tries to create array of length 1, but that failes because class CustomArray is expectiong array.

I want to prevent splice method from initiating a new instance of CustomArray class and instead return normal array (an instance of Array object).

Jsbin link.

解决方案

I want to prevent splice method from initiating a new instance of CostomArray class and instead return normal array (an instance of Array object).

Then you need to create a different method with a different name. The semantics of splice are clearly and precisely defined; they form a contract for the Array type. Having your CostomArray violate that contract would mean it isn't an Array anymore, it's something array-like, and shouldn't extend Array.

Since your method is called remove, that's fine; if you want remove to return Array, not CostomArray, you just need to implement the logic yourself:

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 [];
}


Alternately, of course, make CostomArray's constructor work correctly when called by the various Array.prototype methods. (The one you have in the question works just fine, other than logging something you don't expect with console.log.)

这篇关于在JavaScript的Array子类中使用.splice方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆