ArrayList是一种数据结构,它可以用来存储一组数据。特点是可以动态地增加或删除数据,并且可以随机访问其中的元素。在JavaScript中,没有内置的ArrayList数据结构,但是我们可以使用类对象来实现它。
将集合存储在对象本身上,并使用在 Array.prototype.push 上使用的 call 来调用该方法,使其认为正在处理数组,而它只是像平常一样运作,这是JavaScript 允许我们建立任意的执行上下文。尽管 Object不是数组,但是 push 方法成功地使 Object的 length 属性增长了,就像我们处理一个实际的数组一样,这就是类数组。
在JavaScript 中 数组本身就非常强大,可以存储任意类型,且长度自动扩容,又提供遍历, 过滤等多个操作数组的方法。这里我们将使用push()、splice()、fill()、some()等方法,来实现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
}
这里咱们将结合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 }
以上方法只能添加一个元素,这里将上述方法稍作改造后,则可完成多元素同时添加。
示例:
- // 定义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 }
也可以结合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是类数组容器,所以无法使用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' ]
获取值的方法,同上,也是使用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);
- }
- }