JavaScript内置对象 - Array数组(三)- 自定义ArrayList

        ArrayList是一种数据结构,它可以用来存储一组数据。特点是可以动态地增加或删除数据,并且可以随机访问其中的元素。在JavaScript中,没有内置的ArrayList数据结构,但是我们可以使用类对象来实现它。

        将集合存储在对象本身上,并使用在 Array.prototype.push 上使用的 call 来调用该方法,使其认为正在处理数组,而它只是像平常一样运作,这是JavaScript 允许我们建立任意的执行上下文。尽管 Object不是数组,但是 push 方法成功地使 Object的 length 属性增长了,就像我们处理一个实际的数组一样,这就是类数组。

        在JavaScript 中 数组本身就非常强大,可以存储任意类型,且长度自动扩容,又提供遍历, 过滤等多个操作数组的方法。这里我们将使用push()、splice()、fill()、some()等方法,来实现ArrayList的增、删、改、查等功能。

一、定义ArrayList类

        首选,我们在类的构造函数中,初始化容器的长度,否则在未追加任何数据前,该容器的长度length则为undefined。

在未定义length情况下,代码如下:

// 定义ArrayList对象
class ArrayList{
    /**
     * 构造函数
     */
    constructor(){
       
    }
}

// 实例ArrayList对象
const myArr = new ArrayList();
// 获取容器长度
console.log(myArr.length);

输出结果如下:

undefined

初始化容器长度,代码如下:

// 定义ArrayList对象
class ArrayList{
    /**
     * 构造函数
     */
    constructor(){
       this.length = 0;
    }
}

// 实例ArrayList对象
const myArr = new ArrayList();
// 获取容器长度
console.log(myArr.length);

输出结果如下:

0

二、判断是否为空

        判断容器是否为空,直接判断length是否等于0即可,代码如下:

// 定义ArrayList对象
class ArrayList{
    /**
     * 构造函数
     */
    constructor(){
       this.length = 0;
    }
    
    /**
     * 判断容器是否为空
     */
    isEmpty(){
       return this.length === 0;
    }
}

// 实例ArrayList对象
const myArr = new ArrayList();
// 判断容器是否为空
console.log(myArr.isEmpty());

输出结果:

true

三、添加元素

        这里大家可能对[].push.call不太了解,push 方法是具有通用性,该方法和 call() 或 apply() 一起使用时,可应用在类似数组的对象上。

        先写个简单的示例,让大家了解下如果在Object类对象上使用push等数组方法,代码如下:

const obj = {
    push: Array.prototype.push    
}

// 添加类数组元素
obj.push('a');
obj.push('b', 'd', 'd');

// 输出结果
console.log(obj);

输出结果:

{
  '0': 'a',
  '1': 'b',
  '2': 'd',
  '3': 'd',
  push: [Function: push],
  length: 4
}

3.1 单个元素添加

       这里咱们将结合call完成ArrayList添加元素的功能

示例:

// 定义ArrayList对象
class ArrayList{
    /**
     * 构造函数
     */
    constructor(){
       this.length = 0;
    }
    
    // 略...
    
    /**
     * 添加元素
     * @param value 要添加的元素
     */
    addElement(value){
        [].push.call(this, value);
    }
}

// 实例ArrayList对象
const myArr = new ArrayList();
// 添加元素
myArr.addElement("Hello");
// 输出数组
console.log(myArr);

输出结果:

ArrayList { '0': 'Hello', length: 1 }

3.2 使用arguments添加多个元素

        以上方法只能添加一个元素,这里将上述方法稍作改造后,则可完成多元素同时添加。

示例:

// 定义ArrayList对象
class ArrayList{
    /**
     * 构造函数
     */
    constructor(){
       this.length = 0;
    }
    
    // 略...
    
    /**
     * 添加元素
     */
    addElement(){
        [].push.call(this, ...arguments);
    }
}

// 实例ArrayList对象
const myArr = new ArrayList();
// 添加元素
myArr.addElement("How", "are", "you");
// 输出数组
console.log(myArr);

输出结果:

ArrayList { '0': 'How', '1': 'are', '2': 'you', length: 3 }

3.3 使用数组添加多个元素

        也可以结合apply使用数组一次添加多个元素。

示例:

// 定义ArrayList对象
class ArrayList{
    /**
     * 构造函数
     */
    constructor(){
       this.length = 0;
    }
    
    // 略...
    
    /**
     * 通过数组添加多个元素
     * @param arr 要添加数组
     */
    addElementArray(arr){
        [].push.apply(this, arr);
    }
}

// 实例ArrayList对象
const myArr = new ArrayList();
// 添加元素
myArr.addElementArray(["Nice", "to", "meet", "you"]);
// 输出数组
console.log(myArr);

输出结果:

ArrayList {
  '0': 'Nice',
  '1': 'to',
  '2': 'meet',
  '3': 'you',
  length: 4
}

四、获取元素

        数组中获取元素是通过下标索引进行获取的,这里也使用同样方法即可。

示例:

// 定义ArrayList对象
class ArrayList{
    /**
     * 构造函数
     */
    constructor(){
       this.length = 0;
    }
    
    // 略...
    
    /**
     * 通过索引获取值
     * @param index 索引
     */
    getElement(index){
        return this[index];
    }
}

// 实例ArrayList对象
const myArr = new ArrayList();
// 添加元素
myArr.addElementArray(["Nice", "to", "meet", "you"]);
// 获取索引1位置元素
console.log(myArr.getElement(1));

输出结果:

to

五、删除元素

        在数组中删除某个元素可以使用splice()方法,类数组也使用同样方法。

示例:

// 定义ArrayList对象
class ArrayList{
    /**
     * 构造函数
     */
    constructor(){
       this.length = 0;
    }
    
    // 略...
    
    /**
     * 通过索引删除某个元素
     * @param index 索引
     */ 
    removeElement(index){
        [].splice.call(this, index, 1);
    }
}

// 实例ArrayList对象
const myArr = new ArrayList();
// 添加元素
myArr.addElementArray(["Nice", "to", "meet", "you"]);
// 删除索引1位置元素
myArr.removeElement(1);
//输出数组
console.log(myArr);

输出结果:

ArrayList { '0': 'Nice', '1': 'meet', '2': 'you', length: 3 }

六、清空数组

        如果了解splice()方法的,肯定知道如果删除数量不指定情况下,它会将从指定索引位置及后面所有元素删除,这里咱们就利用这一特性来完成清空数组操作。

示例:

// 定义ArrayList对象
class ArrayList{
    /**
     * 构造函数
     */
    constructor(){
       this.length = 0;
    }
    
    // 略...
    
    /**
     * 清空数组
     */
    clearAll(){
        [].splice.call(this, 0);
    }
}

// 实例ArrayList对象
const myArr = new ArrayList();
// 添加元素
myArr.addElementArray(["Nice", "to", "meet", "you"]);
// 清空所有元素
myArr.clearAll(1);
//输出数组
console.log(myArr);

输出结果:

ArrayList { length: 0 }

七、修改元素

        splice()方法不仅可以删除元素,也可以修改元素,咱们就来体验它的强大之处吧。

示例:

// 定义ArrayList对象
class ArrayList{
    /**
     * 构造函数
     */
    constructor(){
       this.length = 0;
    }
    
    // 略...
    
    /**
     * 修改元素信息
     * @param index 索引
     * @param value 修改后的值
     */
    editElement(index, value){
        [].splice.call(this, index, 1, value);
    }
}

// 实例ArrayList对象
const myArr = new ArrayList();
// 添加元素
myArr.addElementArray(["Nice", "to", "meet", "you"]);
// 修改索引0位置的元素
myArr.editElement(0, "Good");
//输出数组
console.log(myArr);

输出结果:

ArrayList {
  '0': 'Good',
  '1': 'to',
  '2': 'meet',
  '3': 'you',
  length: 4
}

八、查询元素是否存在

        在Array中有个some()方法,指定函数测试只要一条通过则返回true,刚好适用于这里。

示例:

// 定义ArrayList对象
class ArrayList{
    /**
     * 构造函数
     */
    constructor(){
       this.length = 0;
    }
    
    // 略...
    
    /**
     * 判断值是否存在
     */
    containValue(value){
       return [].some.call(this, item => item == value); 
    }
}

// 实例ArrayList对象
const myArr = new ArrayList();
// 添加元素
myArr.addElementArray(["Nice", "to", "meet", "you"]);
// 判断容器中是否存在 you 字符串
console.log(myArr.containValue("you"));
// 判断容器中是否存在 Hello 字符串
console.log(myArr.containValue("Hello"));

输出结果:

true
false

九、获取ArrayList中所有索引

        ArrayList是类数组容器,所以无法使用Array.keys()方法,并且Array.keys()方法返回是一个Iterator迭代器,操作也不便;不过Object对象中也有keys()方法,此方法返回是一个枚举类型字符串数组。

        另外,在前面案例中,大家会发现输出整个数组时,最后一个总是有一个 length: 4 的属性,所以当我们获取key时,length这个键也会在其中,在Object.keys()获取数组后,还需要通过数组中filter()方法进行过滤。

示例:

// 定义ArrayList对象
class ArrayList{
    /**
     * 构造函数
     */
    constructor(){
       this.length = 0;
    }
    
    // 略...
    
    /**
     * 获取所有索引
     */
    elementKeys(){
        let arr = Object.keys(this),
            len = this.length; 
        // 获取数组长度内key即可
        return arr.filter((item, i) => i < len);
    }
    
}

// 实例ArrayList对象
const myArr = new ArrayList();
// 添加元素
myArr.addElementArray(["Nice", "to", "meet", "you"]);
// 获取所有key
console.log(myArr.elementKeys());

        输出结果:

[ '0', '1', '2', '3' ]

十、获取ArrayList中所有值

        获取值的方法,同上,也是使用Object.values()方法进行获取。

示例:

// 定义ArrayList对象
class ArrayList{
    /**
     * 构造函数
     */
    constructor(){
       this.length = 0;
    }
    
    // 略...
    
    /**
     *  获取所有值
     */
    elementValues(){
        let arr = Object.values(this),
            len = this.length;
        // 获取数组长度内value即可
        return arr.filter((item, i) => i < len);
    }
}

// 实例ArrayList对象
const myArr = new ArrayList();
// 添加元素
myArr.addElementArray(["Nice", "to", "meet", "you"]);
// 获取ArrayList中所有值
console.log(myArr.elementValues());

输出结果:

[ 'Nice', 'to', 'meet', 'you' ]

        以上则是此篇讲解所有内容,如果对Array内置对象还不太了解的,可以看下前篇内容,地址:觉醒法师_Vue.js,uni-app,JavaScript-CSDN博客

        当你撑握了更多知识点后,发现像Java或其他高级语言中便利的功能函数,咱们也可以通过javascript实现封装,进而方便我们开发。

        ArrayList类数组代码:

// 定义ArrayList对象
class ArrayList{
    /**
     * 构造函数
     */
    constructor(){
       this.length = 0;
    }
    
    /**
     * 判断容器是否为空
     */
    isEmpty(){
       return this.length === 0;
    }
    
    /**
     * 添加元素
     */
    addElement(){
        [].push.call(this, ...arguments);
    }
    
    /**
     * 通过数组添加多个元素
     * @param arr 要添加数组
     */
    addElementArray(arr){
        [].push.apply(this, arr);
    }
    
    /**
     * 通过索引获取值
     * @param index 索引
     */
    getElement(index){
        return this[index];
    }
    
    /**
     * 通过索引删除某个元素
     * @param index 索引
     */ 
    removeElement(index){
        [].splice.call(this, index, 1);
    }
    
    /**
     * 清空数组
     */
    clearAll(){
        [].splice.call(this, 0);
    }
    
    /**
     * 修改元素信息
     * @param index 索引
     * @param value 修改后的值
     */
    editElement(index, value){
        [].splice.call(this, index, 1, value);
    }
    
    /**
     * 判断值是否存在
     */
    containValue(value){
       return [].some.call(this, item => item == value); 
    }
    
    /**
     * 获取所有索引
     */
    elementKeys(){
        let arr = Object.keys(this),
            len = this.length;
        // 获取数组长度内key即可
        return arr.filter((item, i) => i < len);
    }
    
    /**
     *  获取所有值
     */
    elementValues(){
        let arr = Object.values(this),
            len = this.length;
        // 获取数组长度内value即可
        return arr.filter((item, i) => i < len);
    }
}

猜你喜欢

转载自blog.csdn.net/jiciqiang/article/details/133470770