JavaScript数组类型基础知识归纳总结

一 序言

ECMAScript 中除了Object 类型以外,Array 类型恐怕就是最常用的类型了。而且,ECMAScript 中的数组与其他多数语言中的数组有着相当大的区别。虽然ECMAScript 数组与其他语言中的数组都是数据的有序列表,但与其他语言不同的是,ECMAScript 数组的每一项可以保存任何类型的数据。别的就不多说了本篇文章就是围绕Array类型的基础知识来进行总结

二 声明方式
数组最大长度约42亿9千万,超出则报错
实例化构造函数时 , 若只传入一个数值类型参数 , 则意为声明一个length为该数值的空数组
传入一个非数值类型 , 则意为声明一个只含有该元素的数组
传入多个值 , 则意为声明了一个 由这几个值组成的元素的数组
数组可以省去new简写为Array(1,2,3) , 或者以数组字面量的形式声明
并且可以通过更改length属性来控制数组元素个数 数组中空元素值为undefined
数组元素以逗号隔开 , 但最后一个值后不要跟,否则在IE等浏览器下会出现兼容问题,会多出一个undefined元素
通过length属性也可以向数组末尾添加元素
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var arr = new Array(1);
var arr2 = new Array('1');
var arr3 = new Array(1,2);
var arr4 = Array(1);
var arr5 = Array(1,2);
var arr6 = [1];
arr6.length = 5;
arr6[4] = 444;
arr6[arr6.length] = 'it is over';
console.log(arr);    //output: [undefined × 1]
console.log(arr2);    //output: ["1"]
console.log(arr3);    //output: [1, 2]
console.log(arr4);    //output: [undefined × 1]
console.log(arr5);    //output: [1, 2]
console.log(arr6);    //output: [1, undefined × 3, 444, "it is over"]

三 转换方法
数组调用toString方法 原理是每个元素调用toString 然后以,隔开
调用toLocalString  则是每个元素调用toLocalString方法 然后以,隔开
数组调用join方法 默认返回以,隔开的字符串 若指定字符串,则以指定字符串隔开
?
1
2
3
4
5
var aj = ['1',2,'333'];
console.log(aj.toString());    //output: 1,2,333
console.log(aj.toLocaleString());    //output: 1,2,333
console.log(aj.join('||'));    //output: 1||2||333
console.log(aj);    //output: ["1", 2, "333"]

三 栈方法
数组栈方法  模拟栈这种数据结构 Last In First Out
push用于向数组末尾追加新元素, 返回值为更新数组后的长度
?
1
2
3
4
var colors = ['red','blue'];
var coLen = colors.push('green','yellow');
console.log(colors);    //output: ["red", "blue", "green", "yellow"]
console.log(coLen);    //output: 4
pop用于剔除数组末尾的最后一个元素, 返回值为剔除的那个元素, pop()方法不可传入参数
?
1
2
3
4
var arrPop = [1,2,3,'44','55'];
var order = arrPop.pop();
console.log(arrPop);    //output: [1, 2, 3, "44"]
console.log(order);    //output: 55

四 队列方法
数组队列方法  模拟队列这种数据结构 First In First Out
shift用于剔除数组前端的第1个元素,返回值为剔除的那个元素,shift()方法不可传入参数
?
1
2
3
4
var queue = ['1111','22',333];
var front = queue.shift();
console.log(queue);    //output: ["22", 333]
console.log(front);    //output: 1111
unshift用于向数组前端添加1个元素,返回值为新数组的长度
?
1
2
3
var usLen = queue.unshift('666');
console.log(queue);    //output: ["666", "22", 333]
console.log(usLen);    //output: 3
可以将这些方法一起使用 模拟队列形式
?
1
2
3
4
5
6
7
queue.push('9999'); //向末尾添加元素
queue.shift();      //剔除第一个元素
console.log(queue);    //output: ["22", 333, "9999"]
//或者是
queue.unshift('theFirst'); //向前端添加一个元素
queue.pop();               //剔除最后一个元素
console.log(queue);    //output: ["theFirst", "22", 333]

五 重排序方法
reverse翻转数组 返回值是翻转后的新数组  此方法会改变原有数组
?
1
2
3
4
var rever = [1,30,2,30,40,'a',40,5,4,82];
var v = rever.reverse();
console.log(v);    //output: [82, 4, 5, 40, "a", 40, 30, 2, 30, 1]
console.log(rever);    //output: [82, 4, 5, 40, "a", 40, 30, 2, 30, 1]
sort方法若不传参,则将数组元素转换为字符串后 按字符串的编码大小 升序排列 此方法也会改变原有数组
?
1
2
3
4
var rever = [1,30,2,30,40,'a',40,5,4,82];
var q = rever.sort();
console.log(q);    //output: [1, 2, 30, 30, 4, 40, 40, 5, 82, "a"]
console.log(rever);    //output: [1, 2, 30, 30, 4, 40, 40, 5, 82, "a"]
经典排序算法: 冒泡排序
每次比较数组中相邻的两个元素 符合条件则互换位置 可以看做是 执行一次外层循环 就取出了一个最大或最小值 将其push到数组末尾
每轮外层循环结束后 数组后半部分多出一个最大或最小值 下轮循环的内层循环总次数减少1 下次循环不会对该值进行操作
针对所有元素进行重复比较换位置 直至循环次数为1 最后2个元素进行比较 判断是否互换位置
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var bubble = [49,38,65,97,76,13,27,49,78,34,12,64,5,4,62,99,'cc',98,54,56,17,18,23,34,15,35,25,53,51];
var i = 0, l = bubble.length - 1, s = null;
for(;i < l;i++){
    for(var j = 0;j < l - i;j++){
        if(bubble[j] > bubble[j + 1]){ //此处的判断决定 将最大值还是将最小值push到数组末尾 也就是决定按升序还是按降序排列
            s = bubble[j];
            bubble[j] = bubble[j + 1];
            bubble[j + 1] = s;
        }
    }
}
console.log(bubble);
//output: [4,5,12,13,27,34,38,49,49,62,64,65,76,78,97,99,"cc",15,17,18,23,25,34,35,51,53,54,56,98]
//从结果可以看出 当含有字符串时 排序会被字符串分成2半 这是什么原因呢?
//因为当字符串与数值进行比较时 字符串会被隐式转换为数值 'cc'就会被转换为NaN
//而NaN与一切比较都返回false 所以这种结果是非常合理的
下面这个是我接触冒泡排序之前写的 后来接触了冒泡排序才发现 我写的是什么鬼啊 干脆把这个算法叫做 瞎吉尔排序 吧  (逃
此算法虽然也通过比较元素排序 但不是比较相邻的元素 而且循环次数太多 没有冒泡排序效率高 下面介绍一下它的操作过程 :
将数组中的所有元素 依次与数组中的第i个数进行比较  取出最大或最小值
第一轮循环 依次将数组中所有元素与第一个元素比较 互换位置 循环完毕就能得出数组中的最大值 相当于将其unshift到数组第一个位置
第二次循环 将数组的第二大的值取出 unshift插入数组中 以此类推 ... 最后一次循环unshift最后一个元素
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
var arr = [49,38,65,97,76,13,27,49,78,34,12,64,5,4,62,99,'cc',98,54,56,17,18,23,34,15,35,25,53,51];
var i = 0, l = arr.length;
for(;i < l;i++){
    for(var j = 0;j < l;j++){
        if(arr[j] > arr[i]){ //此处的判断决定 是将最大值还是将最小值unshift到数组前端 也就是决定按降序还是按升序排列
            n = arr[j];
            arr[j] = arr[i];
            arr[i] = n;
        }
    }
}
console.log(arr);
//output: [4,5,12,13,15,17,18,23,25,27,34,34,35,38,49,49,"cc",51,53,54,56,62,64,65,76,78,97,98,99]
//可以看出瞎吉尔排序与冒泡排序略有不同 虽然也被字符串分开了 但是能够接着按顺序排列 不会被该字符串影响而重新排列

六 操作方法
concatslice   这2个方法都有返回值 并且不会改变原有数组
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//concat传入参数即复制一个数组副本,并加入值为该参数的新元素 若传入数组,则将数组拆分,再合并至新数组
var ccArr = [1,'22','33'];
var newccArr = ccArr.concat(123,[666, {name: 'Rihanna'}]);
console.log(newccArr);    //output: [1, "22", "33", 123, 666, {name: "Rihanna"}]
console.log(ccArr);    //output: [1, "22", "33"]
//slice 传入1个或2个number参数
//1个参数即从该参数下标位置开始截取至数组最后一个元素  包含该下标位置的元素和数组最后一个元素
var ssArr = newccArr.slice(1);
console.log(ssArr);    //output: ["22", "33", 123, 666, {name: "Rihanna"}]
//2个参数即从参数1下标位置开始截取截取至参数2下标位置元素,不包含参数2下标位置的元素
var ssArr2 = newccArr.slice(1,2);
console.log(ssArr2);    //output: ["22"]
//若参数为负数 则意为按照length+该负数  例如-1 意思就是length-1 即从最后一个元素开始截取
//若第二个参数比第一个参数小,则永远返回空数组 若参数为空 则返回原数组
var ssArr3 = newccArr.slice(-1,0);
var ssArr4 = newccArr.slice(-3,-1);  //意为从倒数第3个元素开始截取到最后一个元素 不包含最后一个元素
console.log(ssArr3);    //output: []
console.log(ssArr4);    //output: [123, 666]
splice : 删除 替换数组元素   会改变原有数组  返回值是被删除的元素  若没有删除元素 则返回一个空数组
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//传入2个参数  即从第一个参数位置开始  删除共 第二个参数 项元素 删除的元素包括第一个参数位置的元素
var spArr = [66,'oo','cc',33,888,5555];
var spRes = spArr.splice(1,2);
console.log(spArr);    //output: [66, 33, 888, 5555]
console.log(spRes);    //output: ["oo", "cc"]
//若不指定参数,则数组不会有任何改变
//若指定1个参数  则从数组第一个元素开始 删除共 指定参数 项元素
var spArr2 = [66,'oo','cc',33,888,5555];
var spRes2 = spArr2.splice(3);
console.log(spArr2);    //output: [66, "oo", "cc"]
console.log(spRes2);    //output: [33, 888, 5555]
//若指定3或3个以上个参数 即可有插入动作 第3个以后的参数都是要插入的元素  第1个参数为要操作的位置下标
var spArr3 = [66,'oo','cc',33,888,5555];
var spRes3 = spArr3.splice(1,2,'Marilyn','Britney');
console.log(spArr3);    //output: [66, "Marilyn", "Britney", 33, 888, 5555]
console.log(spRes3);    //output: ["oo", "cc"]

七 迭代方法
性能最高的是for 其次是5个迭代方法 最差的是forEach
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
var numbers = [1,2,3,4,5,6,7,8];
//every  数组中的每项元素都返回true则返回true,反之false
var everyResult = numbers.every(function(item, index, array){
    return (item >1)
});
console.log(everyResult);    //output: false
//some  与every相反 数组中只要有一个符合条件的元素  则返回true
var someResult = numbers.some(function(item, index, array){
    return (item > 7)
});
console.log(someResult);   //output: true
//filter 过滤方法  返回数组中符合条件的元素
var filterResult = numbers.filter(function(item, index, array){
    return (item >7);
});
console.log(filterResult);    //output: [8]
//map   地图方法   传入数组  对数组中每个元素进行操作  给出返回结果
var mapResult = numbers.map(function(item, index, array){
    return item * 2
});
console.log(mapResult);    //output: [2, 4, 6, 8, 10, 12, 14, 16]
//forEach  遍历方法  直接对数组每个元素进行操作 没有返回值
numbers.forEach(function(item, index, array){
    console.log('key:'+index+',value:'+item);    //output: key:0,value:1  key:1,value:2......
});

八 归并方法
reduce & reduceRight
?
1
2
3
4
5
6
7
8
9
10
11
//reduce 归并数组 从左开始向右(数组末尾)归并,方法的第一个参数为上个参数,第二个参数为当前参数
var numbers = [1,2,3,4,5,6,7,8];
var sum = numbers.reduce(function(prev, cur, index, array){
    return prev - cur;
});
console.log(sum);    //output: -34
//reduceRight 归并数组  从右开始向左(数组前端)归并,方法的第一个参数为上个参数,第二个参数为当前参数
var sub = numbers.reduceRight(function(prev,cur,index,array){
    return prev - cur;
});
console.log(sub);    //output: -20

发布评论
还没有评论,快来抢沙发吧!