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实现封装,进而方便我们开发。