header-bg.jpg
JavaScript 数组类型基础知识归纳总结
发表于 2017-09-22 21:54
|
分类于 JavaScript
|
评论次数 0
|
阅读次数 1747

attachment/2017/09/22/16941506085857.jpg

array.jpg

在 ECMAScript 中除了 Object 类型以外,Array 类型恐怕就是最常用的类型了。而且 ECMAScript 中的数组与其他多数语言中的数组有着相当大的区别,虽然 ECMAScript 数组与其他语言中的数组都是数据的有序列表,但与其他语言不同的是,ECMAScript 数组的每一项可以保存任何类型的数据。

别的就不多说了,本篇文章就是围绕 Array 类型的基础知识来进行总结

声明方式

数组最大长度约 42 亿 9 千万,超出则报错。

实例化构造函数时,若只传入一个数值类型参数,则意为声明一个 length 为该数值的空数组。

传入一个非数值类型 , 则意为声明一个只含有该元素的数组;传入多个值 , 则意为声明了一个由这几个值组成的元素的数组。

数组可以省去 new 简写为 Array(1,2,3),或者以数组字面量的形式声明,并且可以通过更改 length 属性来控制数组元素个数,数组中空元素值为 undefined

数组元素以逗号隔开,但最后一个值后不要跟,否则在 IE 等浏览器下会出现兼容问题,会多出一个 undefined 元素。

通过 length 属性也可以向数组末尾添加元素,相关用法如下:

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 方法,默认返回以 , 隔开的字符串,若指定字符串,则以指定字符串隔开,相关的几个用法如下:

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 用于向数组末尾追加新元素, 返回值为更新数组后的长度

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() 方法不可传入参数

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 用于剔除数组前端的第一个元素,返回值为剔除的那个元素,shift() 方法不可传入参数,例如:

var queue = ['1111','22',333];
var front = queue.shift();
console.log(queue);    //output: ["22", 333]
console.log(front);    //output: 1111

unshift 用于向数组前端添加一个元素,返回值为新数组的长度,例如:

var usLen = queue.unshift('666');
console.log(queue);// output: ["666", "22", 333]
console.log(usLen);// output: 3

可以将这些方法一起使用模拟队列形式,例如:

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 可以对数组进行翻转,返回值是翻转后的新数组,此方法会改变原有数组,例如:

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方法若不传参,则将数组元素转换为字符串后 按字符串的编码大小 升序排列 此方法也会改变原有数组

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,用法如下:

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]

从结果可以看出,当数组含有字符串元素时,排序会被字符串分成两半分开排序,这是什么原因呢?因为当字符串与数值进行比较时,字符串会被 JS 引擎在底层隐式转换为数值,这里的字符串 cc 会被转换为 NaN,而 NaN 与一切比较都返回 false,所以这种结果是非常合理的。

瞎吉尔排序

下面这个是我接触冒泡排序之前写的 后来接触了冒泡排序才发现 我写的是什么鬼啊 干脆把这个算法叫做 瞎吉尔排序 吧 (逃

此算法虽然也通过比较元素排序 但不是比较相邻的元素 而且循环次数太多 没有冒泡排序效率高 下面介绍一下它的操作过程 :

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 这两个方法都有返回值,并且不会改变原有数组,用法如下:

//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 方法用于删除、替换数组元素,并且会改变原有数组,返回值是被删除的元素,若没有删除元素,则返回一个空数组,例如:

// 传入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,所以应该尽量避免使用,相关用法如下:

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......
});

归并方法

reducereduceRight 的相关用法:

// 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

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