• 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情况下,代码如下:

    1. // 定义ArrayList对象
    2. class ArrayList{
    3. /**
    4. * 构造函数
    5. */
    6. constructor(){
    7. }
    8. }
    9. // 实例ArrayList对象
    10. const myArr = new ArrayList();
    11. // 获取容器长度
    12. console.log(myArr.length);

    输出结果如下:

    undefined

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

    1. // 定义ArrayList对象
    2. class ArrayList{
    3. /**
    4. * 构造函数
    5. */
    6. constructor(){
    7. this.length = 0;
    8. }
    9. }
    10. // 实例ArrayList对象
    11. const myArr = new ArrayList();
    12. // 获取容器长度
    13. console.log(myArr.length);

    输出结果如下:

    0

    二、判断是否为空

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

    1. // 定义ArrayList对象
    2. class ArrayList{
    3. /**
    4. * 构造函数
    5. */
    6. constructor(){
    7. this.length = 0;
    8. }
    9. /**
    10. * 判断容器是否为空
    11. */
    12. isEmpty(){
    13. return this.length === 0;
    14. }
    15. }
    16. // 实例ArrayList对象
    17. const myArr = new ArrayList();
    18. // 判断容器是否为空
    19. console.log(myArr.isEmpty());

    输出结果:

    true

    三、添加元素

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

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

    1. const obj = {
    2. push: Array.prototype.push
    3. }
    4. // 添加类数组元素
    5. obj.push('a');
    6. obj.push('b', 'd', 'd');
    7. // 输出结果
    8. console.log(obj);

    输出结果:

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

    3.1 单个元素添加

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

    示例:

    1. // 定义ArrayList对象
    2. class ArrayList{
    3. /**
    4. * 构造函数
    5. */
    6. constructor(){
    7. this.length = 0;
    8. }
    9. // 略...
    10. /**
    11. * 添加元素
    12. * @param value 要添加的元素
    13. */
    14. addElement(value){
    15. [].push.call(this, value);
    16. }
    17. }
    18. // 实例ArrayList对象
    19. const myArr = new ArrayList();
    20. // 添加元素
    21. myArr.addElement("Hello");
    22. // 输出数组
    23. console.log(myArr);

    输出结果:

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

    3.2 使用arguments添加多个元素

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

    示例:

    1. // 定义ArrayList对象
    2. class ArrayList{
    3. /**
    4. * 构造函数
    5. */
    6. constructor(){
    7. this.length = 0;
    8. }
    9. // 略...
    10. /**
    11. * 添加元素
    12. */
    13. addElement(){
    14. [].push.call(this, ...arguments);
    15. }
    16. }
    17. // 实例ArrayList对象
    18. const myArr = new ArrayList();
    19. // 添加元素
    20. myArr.addElement("How", "are", "you");
    21. // 输出数组
    22. console.log(myArr);

    输出结果:

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

    3.3 使用数组添加多个元素

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

    示例:

    1. // 定义ArrayList对象
    2. class ArrayList{
    3. /**
    4. * 构造函数
    5. */
    6. constructor(){
    7. this.length = 0;
    8. }
    9. // 略...
    10. /**
    11. * 通过数组添加多个元素
    12. * @param arr 要添加数组
    13. */
    14. addElementArray(arr){
    15. [].push.apply(this, arr);
    16. }
    17. }
    18. // 实例ArrayList对象
    19. const myArr = new ArrayList();
    20. // 添加元素
    21. myArr.addElementArray(["Nice", "to", "meet", "you"]);
    22. // 输出数组
    23. console.log(myArr);

    输出结果:

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

    四、获取元素

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

    示例:

    1. // 定义ArrayList对象
    2. class ArrayList{
    3. /**
    4. * 构造函数
    5. */
    6. constructor(){
    7. this.length = 0;
    8. }
    9. // 略...
    10. /**
    11. * 通过索引获取值
    12. * @param index 索引
    13. */
    14. getElement(index){
    15. return this[index];
    16. }
    17. }
    18. // 实例ArrayList对象
    19. const myArr = new ArrayList();
    20. // 添加元素
    21. myArr.addElementArray(["Nice", "to", "meet", "you"]);
    22. // 获取索引1位置元素
    23. console.log(myArr.getElement(1));

    输出结果:

    to

    五、删除元素

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

    示例:

    1. // 定义ArrayList对象
    2. class ArrayList{
    3. /**
    4. * 构造函数
    5. */
    6. constructor(){
    7. this.length = 0;
    8. }
    9. // 略...
    10. /**
    11. * 通过索引删除某个元素
    12. * @param index 索引
    13. */
    14. removeElement(index){
    15. [].splice.call(this, index, 1);
    16. }
    17. }
    18. // 实例ArrayList对象
    19. const myArr = new ArrayList();
    20. // 添加元素
    21. myArr.addElementArray(["Nice", "to", "meet", "you"]);
    22. // 删除索引1位置元素
    23. myArr.removeElement(1);
    24. //输出数组
    25. console.log(myArr);

    输出结果:

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

    六、清空数组

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

    示例:

    1. // 定义ArrayList对象
    2. class ArrayList{
    3. /**
    4. * 构造函数
    5. */
    6. constructor(){
    7. this.length = 0;
    8. }
    9. // 略...
    10. /**
    11. * 清空数组
    12. */
    13. clearAll(){
    14. [].splice.call(this, 0);
    15. }
    16. }
    17. // 实例ArrayList对象
    18. const myArr = new ArrayList();
    19. // 添加元素
    20. myArr.addElementArray(["Nice", "to", "meet", "you"]);
    21. // 清空所有元素
    22. myArr.clearAll(1);
    23. //输出数组
    24. console.log(myArr);

    输出结果:

    ArrayList { length: 0 }

    七、修改元素

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

    示例:

    1. // 定义ArrayList对象
    2. class ArrayList{
    3. /**
    4. * 构造函数
    5. */
    6. constructor(){
    7. this.length = 0;
    8. }
    9. // 略...
    10. /**
    11. * 修改元素信息
    12. * @param index 索引
    13. * @param value 修改后的值
    14. */
    15. editElement(index, value){
    16. [].splice.call(this, index, 1, value);
    17. }
    18. }
    19. // 实例ArrayList对象
    20. const myArr = new ArrayList();
    21. // 添加元素
    22. myArr.addElementArray(["Nice", "to", "meet", "you"]);
    23. // 修改索引0位置的元素
    24. myArr.editElement(0, "Good");
    25. //输出数组
    26. console.log(myArr);

    输出结果:

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

    八、查询元素是否存在

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

    示例:

    1. // 定义ArrayList对象
    2. class ArrayList{
    3. /**
    4. * 构造函数
    5. */
    6. constructor(){
    7. this.length = 0;
    8. }
    9. // 略...
    10. /**
    11. * 判断值是否存在
    12. */
    13. containValue(value){
    14. return [].some.call(this, item => item == value);
    15. }
    16. }
    17. // 实例ArrayList对象
    18. const myArr = new ArrayList();
    19. // 添加元素
    20. myArr.addElementArray(["Nice", "to", "meet", "you"]);
    21. // 判断容器中是否存在 you 字符串
    22. console.log(myArr.containValue("you"));
    23. // 判断容器中是否存在 Hello 字符串
    24. console.log(myArr.containValue("Hello"));

    输出结果:

    true
    false

    九、获取ArrayList中所有索引

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

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

    示例:

    1. // 定义ArrayList对象
    2. class ArrayList{
    3. /**
    4. * 构造函数
    5. */
    6. constructor(){
    7. this.length = 0;
    8. }
    9. // 略...
    10. /**
    11. * 获取所有索引
    12. */
    13. elementKeys(){
    14. let arr = Object.keys(this),
    15. len = this.length;
    16. // 获取数组长度内key即可
    17. return arr.filter((item, i) => i < len);
    18. }
    19. }
    20. // 实例ArrayList对象
    21. const myArr = new ArrayList();
    22. // 添加元素
    23. myArr.addElementArray(["Nice", "to", "meet", "you"]);
    24. // 获取所有key
    25. console.log(myArr.elementKeys());

            输出结果:

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

    十、获取ArrayList中所有值

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

    示例:

    1. // 定义ArrayList对象
    2. class ArrayList{
    3. /**
    4. * 构造函数
    5. */
    6. constructor(){
    7. this.length = 0;
    8. }
    9. // 略...
    10. /**
    11. * 获取所有值
    12. */
    13. elementValues(){
    14. let arr = Object.values(this),
    15. len = this.length;
    16. // 获取数组长度内value即可
    17. return arr.filter((item, i) => i < len);
    18. }
    19. }
    20. // 实例ArrayList对象
    21. const myArr = new ArrayList();
    22. // 添加元素
    23. myArr.addElementArray(["Nice", "to", "meet", "you"]);
    24. // 获取ArrayList中所有值
    25. console.log(myArr.elementValues());

    输出结果:

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

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

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

            ArrayList类数组代码:

    1. // 定义ArrayList对象
    2. class ArrayList{
    3. /**
    4. * 构造函数
    5. */
    6. constructor(){
    7. this.length = 0;
    8. }
    9. /**
    10. * 判断容器是否为空
    11. */
    12. isEmpty(){
    13. return this.length === 0;
    14. }
    15. /**
    16. * 添加元素
    17. */
    18. addElement(){
    19. [].push.call(this, ...arguments);
    20. }
    21. /**
    22. * 通过数组添加多个元素
    23. * @param arr 要添加数组
    24. */
    25. addElementArray(arr){
    26. [].push.apply(this, arr);
    27. }
    28. /**
    29. * 通过索引获取值
    30. * @param index 索引
    31. */
    32. getElement(index){
    33. return this[index];
    34. }
    35. /**
    36. * 通过索引删除某个元素
    37. * @param index 索引
    38. */
    39. removeElement(index){
    40. [].splice.call(this, index, 1);
    41. }
    42. /**
    43. * 清空数组
    44. */
    45. clearAll(){
    46. [].splice.call(this, 0);
    47. }
    48. /**
    49. * 修改元素信息
    50. * @param index 索引
    51. * @param value 修改后的值
    52. */
    53. editElement(index, value){
    54. [].splice.call(this, index, 1, value);
    55. }
    56. /**
    57. * 判断值是否存在
    58. */
    59. containValue(value){
    60. return [].some.call(this, item => item == value);
    61. }
    62. /**
    63. * 获取所有索引
    64. */
    65. elementKeys(){
    66. let arr = Object.keys(this),
    67. len = this.length;
    68. // 获取数组长度内key即可
    69. return arr.filter((item, i) => i < len);
    70. }
    71. /**
    72. * 获取所有值
    73. */
    74. elementValues(){
    75. let arr = Object.values(this),
    76. len = this.length;
    77. // 获取数组长度内value即可
    78. return arr.filter((item, i) => i < len);
    79. }
    80. }

  • 相关阅读:
    Vue框架总结(五、Vue配置代理)
    MiKTeX安装后,Latex编译后PDF无法预览,是灰色的
    CN考研真题知识点二轮归纳(5)
    机器学习方法之k近邻方法的综述
    分布式存储系统之Ceph集群RadosGW基础使用
    Python 迭代器与生成器
    三合一的王炸!主打特价中的特价Dana Chen 凌恩生物 2024-02-29 08:00 内蒙古
    消息队列(MQ)的简单介绍
    关于头文件的使用
    实现一个todoList可直接操作数据(上移、下移、置顶、置底)
  • 原文地址:https://blog.csdn.net/jiciqiang/article/details/133470770