Web/04-JavaScript基础/16-数组的常见方法&数组的遍历.md
2020-05-15 20:05:56 +08:00

1251 lines
33 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

## 前言
**数组的四个基本方法如下**数组元素的添加和删除
| 方法 | 描述 | 备注 |
|:-------------|:-------------|:-------------|
| push() | 向数组的**最后面**插入一个或多个元素返回结果为**该数组新的长度**| 会改变原数组|
| pop() | 删除数组中的**最后一个**元素返回结果为**被删除的元素**| 会改变原数组|
| unshift() | 在数组**最前面**插入一个或多个元素返回结果为**该数组新的长度**| 会改变原数组|
| shift() | 删除数组中的**第一个**元素返回结果为**被删除的元素**| 会改变原数组|
**数组的常见方法如下**
| 方法 | 描述 | 备注 |
|:-------------|:-------------|:-------------|
| slice() | 从数组中**提取**指定的一个或多个元素返回结果为**新的数组**| 不会改变原数组|
| splice() | 从数组中**删除**指定的一个或多个元素返回结果为**新的数组**| 会改变原数组|
| concat() | 连接两个或多个数组返回结果为**新的数组**| 不会改变原数组|
| join() | 将数组转换为字符串返回结果为**转换后的字符串**| 不会改变原数组|
| reverse() | 反转数组返回结果为**反转后的数组**| 会改变原数组|
| sort() | 对数组的元素,默认按照**Unicode编码**从小到大进行排序| 会改变原数组|
**遍历数组的方法如下**
| 方法 | 描述 | 备注 |
|:-------------|:-------------|:-------------|
| for循环 | 这个大家都懂| |
| forEach()| for循环类似但需要兼容IE8以上 |forEach() 没有返回值也就是说它的返回值是 undefined|
| map()| 对原数组中的每一项进行加工将组成新的数组 | 不会改变原数组 |
| filter()| 对数组中的每一项运行回调函数该函数返回结果是true的项将组成新的数组返回结果为**新的数组**可以起到过滤的作用| 不会改变原数组|
| every()| 如果有一项返回false则停止遍历此方法返回 false | 一假即假要求每一项都返回true最终的结果才返回true |
| some()| 只要有一项返回true则停止遍历此方法返回true | 一真即真要求每一项都返回false最终的结果才返回false|
| reduce | 为数组中的每一个元素依次执行回调函数 | |
**数组的其他方法如下**
| 方法 | 描述 | 备注 |
|:-------------|:-------------|:-------------|
| indexOf(value) | 从前往后索引获取 value 在数组中的第一个下标 | |
| lastIndexOf(value) | 从后往前索引获取 value 在数组中的最后一个下标 | |
| find(function()) | 找出**第一个**满足指定条件返回true的元素 | |
| findIndex(function()) | 找出**第一个**满足指定条件返回true的元素的index | |
| Array.from(arrayLike) | **伪数组**转化为**真数组**| |
| Array.of(value1, value2, value3) | **一系列值**转换成数组| |
## 数组的四个基本方法数组元素的添加和删除
### push()
`push()`向数组的**最后面**插入一个或多个元素返回结果为**该数组新的长度**
语法
```javascript
数组的新长度 = 数组.push(元素);
```
代码举例
```javascript
var arr = ["王一", "王二", "王三"];
var result1 = arr.push("王四"); // 末尾插入一个元素
var result2 = arr.push("王五", "王六"); // 末尾插入多个元素
console.log(result1); // 打印结果4
console.log(result2); // 打印结果6
console.log(JSON.stringify(arr)); // 打印结果:["王一","王二","王三","王四","王五","王六"]
```
### pop()
`pop()`删除数组中的**最后一个**元素返回结果为**被删除的元素**
语法
```javascript
被删除的元素 = 数组.pop();
```
代码举例
```javascript
var arr = ["王一", "王二", "王三"];
var result1 = arr.pop();
console.log(result1); // 打印结果:王三
console.log(JSON.stringify(arr)); // 打印结果:["王一","王二"]
```
### unshift()
`unshift()`在数组**最前面**插入一个或多个元素返回结果为**该数组新的长度**插入元素后其他元素的索引会依次调整
语法
```javascript
数组的新长度 = 数组.unshift(元素);
```
代码举例
```javascript
var arr = ["王一", "王二", "王三"];
var result1 = arr.unshift("王四"); // 最前面插入一个元素
var result2 = arr.unshift("王五", "王六"); // 最前面插入多个元素
console.log(result1); // 打印结果4
console.log(result2); // 打印结果6
console.log(JSON.stringify(arr)); // 打印结果:["王五","王六","王四","王一","王二","王三"]
```
### shift()
`shift()`删除数组中的**第一个**元素返回结果为**被删除的元素**
语法
```javascript
被删除的元素 = 数组.shift();
```
代码举例
```javascript
var arr = ["王一", "王二", "王三"];
var result1 = arr.shift();
console.log(result1); // 打印结果:王一
console.log(JSON.stringify(arr)); // 打印结果:["王二","王三"]
```
接下来我们讲一下数组的其他常见方法
## slice()
`slice()`从数组中**提取**指定的一个或者多个元素返回结果为**新的数组**不会改变原来的数组
备注该方法不会改变原数组而是将截取到的元素封装到一个新数组中返回
**语法**
```javascript
新数组 = 原数组.slice(开始位置的索引, 结束位置的索引); //注意:包含开始索引,不包含结束索引
```
举例
```javascript
var arr = ["a", "b", "c", "d", "e", "f"];
var result1 = arr.slice(2); //从第二个值开始提取
var result2 = arr.slice(-2); //提取最后两个元素
var result3 = arr.slice(2, 4); //提取从第二个到第四个之间的值(不包括第四个值)
var result4 = arr.slice(4, 2); //空
console.log("arr:" + JSON.stringify(arr));
console.log("result1:" + JSON.stringify(result1));
console.log("result2:" + JSON.stringify(result2));
console.log("result3:" + JSON.stringify(result3));
console.log("result4:" + JSON.stringify(result4));
```
打印结果
```javascript
arr:["a","b","c","d","e","f"]
result1:["c","d","e","f"]
result2:["e","f"]
result3:["c","d"]
result4:[]
```
**补充**
很多前端开发人员会用 slice()将伪数组转化为真数组写法如下
```javascript
array = Array.prototye.slice.call(arrayLike)
或者
array = [].slice.call(arrayLike)
```
ES6 看不下去这种蹩脚的转化方法于是出了一个新的 API专门用来将伪数组转化成真数组
```javascript
array = Array.from(arrayLike)
```
## splice()
`splice()`从数组中**删除**指定的一个或多个元素返回结果为**新的数组**会改变原来的数组
备注该方法会改变原数组会将指定元素从原数组中删除被删除的元素会封装到一个新的数组中返回
语法
```javascript
新数组 = 原数组.splice(起始索引index, 需要删除的个数, 第三个参数, 第四个参数...);
```
上方语法中第三个及之后的参数表示向原数组中添加新的元素这些元素将会自动插入到开始位置索引的前面
举例1
```javascript
var arr1 = ["a", "b", "c", "d", "e", "f"];
var result1 = arr1.splice(1); //从第index为1的位置开始删除元素
console.log("arr1" + JSON.stringify(arr1));
console.log("result1" + JSON.stringify(result1));
```
打印结果
```
arr1["a"]
result1["b","c","d","e","f"]
```
举例2
```javascript
var arr2 = ["a", "b", "c", "d", "e", "f"];
var result2 = arr2.splice(-2); //删除最后两个元素
console.log("arr2" + JSON.stringify(arr2));
console.log("result2" + JSON.stringify(result2));
```
打印结果
```
arr2["a","b","c","d"]
result2["e","f"]
```
举例3
```javascript
var arr3 = ["a", "b", "c", "d", "e", "f"];
var result3 = arr3.splice(1, 3); //从第index为1的位置开始删除元素,一共删除三个元素
console.log("arr3" + JSON.stringify(arr3));
console.log("result3" + JSON.stringify(result3));
```
打印结果
```
arr3["a","e","f"]
result3["b","c","d"]
```
举例4我们来看看**第三个参数**的用法
```javascript
var arr4 = ["a", "b", "c", "d", "e", "f"];
//从第index为1的位置开始删除元素,一共删除三个元素。并且在 index=1 的前面追加两个元素
var result4 = arr4.splice(1, 3, "千古壹号", "vae");
console.log("arr4" + JSON.stringify(arr4));
console.log("result4" + JSON.stringify(result4));
```
打印结果
```javascript
arr4["a","千古壹号","vae","e","f"]
result4["b","c","d"]
```
## concat()
`concat()`连接两个或多个数组返回结果为**新的数组**不会改变原数组
语法
```javascript
新数组 = 数组1.concat(数组2, 数组3 ...);
```
举例
```javascript
var arr1 = [1, 2, 3];
var arr2 = ["a", "b", "c"];
var arr3 = ["千古壹号", "vae"];
var result1 = arr1.concat(arr2);
var result2 = arr2.concat(arr1, arr3);
console.log("arr1 =" + JSON.stringify(arr1));
console.log("arr2 =" + JSON.stringify(arr2));
console.log("arr3 =" + JSON.stringify(arr3));
console.log("result1 =" + JSON.stringify(result1));
console.log("result2 =" + JSON.stringify(result2));
```
打印结果
```javascript
arr1 =[1,2,3]
arr2 =["a","b","c"]
arr3 =["千古壹号","vae"]
result1 =[1,2,3,"a","b","c"]
result2 =["a","b","c",1,2,3,"千古壹号","vae"]
```
从打印结果中可以看到原数组并没有被修改
## join()
`join()`将数组转换为字符串返回结果为**转换后的字符串**不会改变原来的数组
补充`join()`方法可以指定一个**字符串**作为参数这个字符串将会成为数组中元素的**连接符**如果不指定连接符则默认使用 `,` 作为连接符此时和 `toString()的效果是一致的`
语法
```javascript
新的字符串 = 原数组.join(参数); // 参数选填
```
代码举例
```javascript
var arr = ["a", "b", "c"];
var result1 = arr.join(); // 这里没有指定连接符,所以默认使用 , 作为连接符
var result2 = arr.join("-"); // 使用指定的字符串作为连接符
console.log(typeof arr); // 打印结果object
console.log(typeof result1); // 打印结果string
console.log("arr =" + JSON.stringify(arr));
console.log("result1 =" + JSON.stringify(result1));
console.log("result2 =" + JSON.stringify(result2));
```
上方代码中最后三行的打印结果是
```javascript
arr =["a","b","c"]
result1 =a,b,c
result2 =a-b-c
```
## reverse()
`reverse()`反转数组返回结果为**反转后的数组**会改变原来的数组
语法
```
反转后的数组 = 数组.reverse();
```
举例
```javascript
var arr = ["a", "b", "c", "d", "e", "f"];
var result = arr.reverse(); // 将数组 arr 进行反转
console.log("arr =" + JSON.stringify(arr));
console.log("result =" + JSON.stringify(result));
```
打印结果
```javascript
arr =["f","e","d","c","b","a"]
result =["f","e","d","c","b","a"]
```
从打印结果可以看出原来的数组已经被改变了
## sort()方法
> sort()方法要好好理解所以我们单独用一大段来讲
`sort()`对数组的元素进行从小到大来排序会改变原来的数组
### sort()方法举例无参时
如果在使用 sort() 方法时不带参则默认按照**Unicode编码**从小到大进行排序
**举例1**当数组中的元素为字符串时
```javascript
var arr1 = ["e", "b", "d", "a", "f", "c"];
var result = arr1.sort(); // 将数组 arr1 进行排序
console.log("arr1 =" + JSON.stringify(arr1));
console.log("result =" + JSON.stringify(result));
```
打印结果
```javascript
arr1 =["a","b","c","d","e","f"]
result =["a","b","c","d","e","f"]
```
从上方的打印结果中我们可以看到sort方法会改变原数组而且方法的返回值也是同样的结果
**举例2**当数组中的元素为数字时
```javascript
var arr2 = [5, 2, 11, 3, 4, 1];
var result = arr2.sort(); // 将数组 arr2 进行排序
console.log("arr2 =" + JSON.stringify(arr2));
console.log("result =" + JSON.stringify(result));
```
打印结果
```javascript
arr2 =[1,11,2,3,4,5]
result =[1,11,2,3,4,5]
```
上方的打印结果中你会发现使用 sort() 排序后数字`11`竟然在数字`2`的前面这是为啥呢因为上面讲到了`sort()`方法是按照**Unicode编码**进行排序的
那如果我想让 arr2 里的数字完全按照从小到大排序怎么操作呢继续往下看
### sort()方法举例带参时
如果在 sort()方法中带参我们就可以**自定义**排序规则具体做法如下
我们可以在sort()添加一个回调函数来指定排序规则回调函数中需要定义两个形参浏览器将会分别使用数组中的元素作为实参去调用回调函数
浏览器根据回调函数的返回值来决定元素的排序重要
- 如果返回一个大于0的值则元素会交换位置
- 如果返回一个小于0的值则元素位置不变
- 如果返回一个0则认为两个元素相等则不交换位置
**代码举例**
```javascript
var arr3 = [5, 2, 11, 3, 4, 1];
// 自定义排序规则
var result = arr3.sort(function(a, b) {
if (a > b) { // 如果 a 大于 b则交换 a 和 b 的位置
return 1;
} else if (a < b) { // 如果 a 小于 b则位置不变
return -1;
} else { // 如果 a 等于 b则位置不变
return 0;
}
});
console.log("arr3 =" + JSON.stringify(arr3));
console.log("result =" + JSON.stringify(result));
```
打印结果
```javascript
arr3 =[1,2,3,4,5,11]
result =[1,2,3,4,5,11]
```
上方代码的写法太啰嗦了其实也可以简化为如下写法
**代码优化**冒泡排序
```javascript
var arr3 = [5, 2, 11, 3, 4, 1];
// 自定义排序规则
var result = arr3.sort(function(a, b) {
return a - b; // 升序排列
// return b - a; // 降序排列
});
console.log("arr3 =" + JSON.stringify(arr3));
console.log("result =" + JSON.stringify(result));
```
打印结果
```javascript
arr3 =[1,2,3,4,5,11]
result =[1,2,3,4,5,11]
```
### sort方法举例将数组从小到大排序
将数组从小到大排序这个例子很常见
下面这段代码在实际开发中经常用到一定要掌握完整代码如下
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<script>
let dataList = [
{
title: '品牌鞋子,高品质低价入手',
publishTime: 200,
},
{
title: '不是很贵,但是很暖',
publishTime: 100,
},
{
title: '无法拒绝的美食,跟我一起吃吃',
publishTime: 300,
},
];
console.log('qianguyihao 排序前的数组:' + JSON.stringify(dataList));
// 将dataList 数组,按照 publishTime 字段,从小到大排序。(会改变原数组)
dataList.sort(function(a, b) {
return parseInt(a.publishTime) - parseInt(b.publishTime);
});
console.log('qianguyihao 排序后的数组:' + JSON.stringify(dataList));
</script>
</body>
</html>
```
打印结果
```
qianguyihao 排序前的数组:[
{"title":"品牌鞋子,高品质低价入手","publishTime":200},
{"title":"不是很贵,但是很暖","publishTime":100},
{"title":"无法拒绝的美食,跟我一起吃吃","publishTime":300}]
qianguyihao 排序后的数组:[
{"title":"不是很贵,但是很暖","publishTime":100},
{"title":"品牌鞋子,高品质低价入手","publishTime":200},
{"title":"无法拒绝的美食,跟我一起吃吃","publishTime":300}]
```
## 概念数组的遍历
遍历数组即获取并操作数组中的每一个元素在我们的实战开发中使用得非常频繁
遍历数组的方法包括every()filter()forEach()map()some()
PS这几个方法**不会修改原数组**
语法格式
```
数组/boolean/无 = 数组.every/filter/forEach/map/some(
function(item, index, arr){
程序和返回值;
})
```
有了这几种方法就可以替代一些for循环了下面依次来介绍
## for循环 遍历
举例
```javascript
var arr = ["生命壹号","许嵩","永不止步"];
for(var i = 0;i<arr.length;i++){
console.log(arr[i]); // arr[i]代表的是数组中的每一个元素i
}
console.log(arr);
```
打印结果
![](http://img.smyhvae.com/20180124_2008.png)
## forEach() 遍历
> `forEach()` 这种遍历方法只支持IE8以上的浏览器IE8及以下的浏览器均不支持该方法所以如果需要兼容IE8则不要使用forEach改为使用for循环来遍历即可
forEach()方法需要一个函数作为参数这种函数是由我们创建但是不由我们调用的我们称为回调函数
数组中有几个元素该回调函数就会执行几次执行完毕后浏览器会将遍历到的元素
回调函数中传递三个参数
- 第一个参数就是当前正在遍历的元素
- 第二个参数就是当前正在遍历的元素的索引
- 第三个参数就是正在遍历的数组
代码举例
```javascript
var arr = ["王一", "王二", "王三"];
arr.forEach(function(item, index, obj) {
console.log("item:" + item);
console.log("index:" + index);
console.log("obj:" + obj);
console.log("----------");
});
```
打印结果
```javascript
item:王一
index:0
obj:王一,王二,王三
----------
item:王二
index:1
obj:王一,王二,王三
----------
item:王三
index:2
obj:王一,王二,王三
----------
```
注意forEach() 的返回值是 undefined也就是说它没有返回值如果你尝试 `tempArry = arr.forEach()`这种方式来接收是达不到效果的
## map()方法
解释对数组中每一项运行回调函数返回该函数的结果组成的新数组返回的是**加工之后**的新数组
**举例1**拷贝的过程中改变数组元素的值
有一个已知的数组arr1我要求让arr1中的每个元素的值都加10这里就可以用到 map 方法代码举例
```javascript
var arr1 = [1, 3, 6, 2, 5, 6];
var arr2 = arr1.map(function (item, index) {
return item + 10; //让arr1中的每个元素加10
})
console.log(arr2);
```
打印结果
![](http://img.smyhvae.com/20180402_0938.png)
**举例2**重要案例实际开发中经常用到
将A数组中某个属性的值存储到B数组中代码举例
```javascript
const arr1 = [
{ name: '千古壹号', age: '28' },
{ name: '许嵩', age: '32' },
];
// 将数组 arr1 中的 name 属性,存储到 数组 arr2 中
const arr2 = arr1.map(item => item.name);
// 将数组 arr1 中的 name、age这两个属性改一下“键”的名字存储到 arr3中
const arr3 = arr1.map(item => ({
myName: item.name,
myAge: item.age,
})); // 将数组 arr1 中的 name 属性,存储到 数组 arr2 中
console.log('arr1:' + JSON.stringify(arr1));
console.log('arr2:' + JSON.stringify(arr2));
console.log('arr3:' + JSON.stringify(arr3));
```
打印结果
```
arr1:[{"name":"千古壹号","age":"28"},{"name":"许嵩","age":"32"}]
arr2:["千古壹号","许嵩"]
arr3:[{"myName":"千古壹号","myAge":"28"},{"myName":"许嵩","myAge":"32"}]
```
map的应用场景主要就是以上两种
## filter()
解释对数组中的**每一项**运行回调函数该函数返回结果是true的项将组成新的数组返回值就是这个新的数组
**举例1**找出数组 arr1 中大于4的元素返回一个新的数组代码如下
```javascript
var arr1 = [1, 3, 6, 2, 5, 6];
var arr2 = arr1.filter(function(item, index) {
return item > 4; //将arr1中大于4的元素返回组成新的数组
});
console.log(JSON.stringify(arr2));
```
打印结果
```
[6,5,6]
```
上方代码的ES6写法
```javascript
const arr1 = [1, 3, 6, 2, 5, 6];
const arr2 = arr1.filter(item=> item > 4); //将arr1中大于4的元素返回组成新的数组
console.log(JSON.stringify(arr2));
```
**举例2**
获取数组A中指定类型的对象放到数组B中代码举例如下
```javascript
const arr1 = [
{ name: '许嵩', type: '一线' },
{ name: '周杰伦', type: '过气' },
{ name: '邓紫棋', type: '一线' },
];
const arr2 = arr1.filter(item => item.type == '一线'); // 筛选出一线歌手
console.log(JSON.stringify(arr2));
```
打印结果
```javascript
[{"name":"许嵩","type":"一线"},{"name":"邓紫棋","type":"一线"}]
```
## every()方法
`every()`对数组中每一项运行回调函数如果都返回trueevery就返回true如果有一项返回false则停止遍历此方法返回false
注意every()方法的返回值是boolean值参数是回调函数
举例
```javascript
var arr1 = ["千古", "宿敌", "南山忆", "素颜"];
var bool1 = arr1.every(function (element, index, array) {
if (element.length > 2) {
return false;
}
return true;
});
console.log(bool1); //输出结果false。只要有一个元素的长度是超过两个字符的就返回false
var arr2 = ["千古", "宿敌", "南山", "素颜"];
var bool2 = arr2.every(function (element, index, array) {
if (element.length > 2) {
return false;
}
return true;
});
console.log(bool2); //输出结果true。因为每个元素的长度都是两个字符。
```
## some()方法
`some()`对数组中每一项运行回调函数只要有一项返回true则停止遍历此方法返回true
注意some()方法的返回值是boolean值
### reduce()方法
> reduce的发音[rɪ'djuːs]。中文含义是减少。
`reduce()`:为数组中的每一个元素,依次执行回调函数。
**语法**
```javascript
arr.reduce(
function(previousValue, item, index, arr) {
}, initialValue)
```
参数解释:
- previousValue上一次调用回调函数时的返回值或者初始值
- currentValue当前正在处理的数组元素
- currentIndex当前正在处理的数组元素下标
- array调用reduce()方法的数组
- initialValue可选的初始值作为第一次调用回调函数时传给 previousValue 的值)
备注:如果能熟练使用 reduce 的用法,将能替代很多其他的数组方法。
**举例1**
计算数组中所有元素项的总和。代码实现:
```javascript
var arr = [2, 0, 1, 9, 6];
sumValue = arr.reduce(function(total, item) { // 计算 arr 数组中,所有元素项的综合
return total + item;
}, 0);
console.log('sumValue:' + sumValue); // 打印结果18
```
## indexOf() 和 lastIndexOf():获取数据的索引
**语法**
```javascript
索引值 = 数组.indexOf(value);
索引值 = 数组.lastIndexOf(value);
```
**解释**
- indexOf(value):从前往后索引,获取 value 在数组中的第一个下标。
- lastIndexOf(value) :从后往前索引,获取 value 在数组中的最后一个下标。
**作用**
利用这个方法,我们可以判断某个值是否在指定的数组中。**如果没找到则返回`-1`**。
**举例1**
```javascript
var arr = ["a","b","c","d","e","d","c"];
console.log(arr.indexOf("c")); //从前往后,找第一个"c"在哪个位置
console.log(arr.lastIndexOf("d")); //从后往前,找第一个"d"在哪个位置
```
打印结果:
![](http://img.smyhvae.com/20180126_1125.png)
**举例2**:判断某个值是否在数组中
```javascript
var arr = ["29926392220", "29965620629", "28003663436", " ", "28818504366"];
var str = [
{name:"smyh", id: "12334"},
{name:"vae", id: "28818504366"}
];
str.filter(item => {
console.log(arr.indexOf(item.id));
})
```
## find()
**语法**
```javascript
find(function(item, index, arr){return true})
```
**作用**:找出**第一个**满足「指定条件返回true」的元素。
备注:一旦找到符合条件的第一个元素,将不再继续往下遍历。
举例:
```javascript
let arr = [2, 3, 2, 5, 7, 6];
let result = arr.find(function (item, index) {
return item > 4; //遍历数组arr一旦发现有第一个元素大于4就把这个元素返回
});
console.log(result); //打印结果5
```
## findIndex()
**语法**
```javascript
findIndex(function(item, index, arr){return true})
```
**作用**:找出**第一个**满足「指定条件返回true」的元素的index。
举例:
> 我们直接把上面的代码中的find方法改成findIndex来看看效果。
```javascript
let arr = [2, 3, 2, 5, 7, 6];
let result = arr.findIndex(function (item, index) {
return item > 4; //遍历数组arr一旦发现有第一个元素大于4就把这个元素的index返回
});
console.log(result); //打印结果3
```
## Array.from()
**语法**
```javascript
array = Array.from(arrayLike)
```
**作用**:将**伪数组**或可遍历对象转换为**真数组**。
**举例:**
```html
<body>
<button>按钮1</button>
<button>按钮2</button>
<button>按钮3</button>
<script>
let btnArray = document.getElementsByTagName('button');
console.log(btnArray);
console.log(btnArray[0]);
</script>
</body>
```
上面的布局中有三个button标签我们通过`getElementsByTagName`获取到的`btnArray`实际上是**伪数组**,并不是真实的数组:
![](http://img.smyhvae.com/20180402_1116.png)
既然`btnArray`是伪数组,它就不能使用数组的一般方法,否则会报错:
![](http://img.smyhvae.com/20180402_1121.png)
解决办法:采用`Array.from`方法将`btnArray`这个伪数组转换为真数组即可:
```javascript
Array.from(btnArray);
```
然后就可以使用数组的一般方法了:
![](http://img.smyhvae.com/20180402_1125.png)
**伪数组与真数组的区别**
伪数组的原型链中没有 Array.prototype而真数组的原型链中有 Array.prototype。因此伪数组没有 pop、join等属性。
### Array.of()
**语法**
```javascript
Array.of(value1, value2, value3)
```
**作用**:将一系列值转换成数组。
**举例**
```javascript
let arr = Array.of(1, 'abc', true);
console.log(arr);
```
## isArray():判断是否为数组
```javascript
布尔值 = Array.isArray(被检测的值) ;
```
以前,我们会通过 `A instanceof B`来判断 A 是否属于 B 类型。但是在数组里,这种 instanceof 方法已经用的不多了因为有下面isArray()方法。
## toString():转换数组
```javascript
字符串 = 数组.toString();
```
解释:把数组转换成字符串,每一项用`,`分割。
## valueOf():返回数组本身
```javascript
数组本身 = 数组.valueOf();
```
这个方法的意义不大。因为我们指直接写数组对象的名字,就已经是数组本身了。
## 数组练习
### splice()练习:数组去重
代码实现:
```javascript
//创建一个数组
var arr = [1, 2, 3, 2, 2, 1, 3, 4, 2, 5];
//去除数组中重复的数字
//获取数组中的每一个元素
for (var i = 0; i < arr.length; i++) {
//console.log(arr[i]);
/*获取当前元素后的所有元素*/
for (var j = i + 1; j < arr.length; j++) {
//console.log("---->"+arr[j]);
//判断两个元素的值是否相等
if (arr[i] == arr[j]) {
//如果相等则证明出现了重复的元素则删除j对应的元素
arr.splice(j, 1);
//当删除了当前j所在的元素以后后边的元素会自动补位
//此时将不会在比较这个元素我需要再比较一次j所在位置的元素
//使j自减
j--;
}
}
}
console.log(arr);
```
### 清空数组
清空数组,有以下几种方式:
```javascript
var array = [1,2,3,4,5,6];
array.splice(0); //方式1删除数组中所有项目
array.length = 0; //方式2length属性可以赋值在其它语言中length是只读
array = []; //方式3推荐
```
### 练习1
**问题**:将一个字符串数组输出为`|`分割的形式,比如“千古|宿敌|素颜”。使用两种方式实现。
答案:
方式1不推荐
```javascript
var arr = ["千古","宿敌","素颜"];
var str = arr[0];
var separator = "|";
for(var i = 1;i< arr.length;i++) {
str += separator+arr[i]; //从第1个数组元素开始每个元素前面加上符号"|"
}
console.log(str);
```
输出结果:
![](http://img.smyhvae.com/20180126_1336.png)
不推荐这种方式因为由于字符串的不变性str拼接过多的话容易导致内存溢出很多个str都堆放在栈里
方式2推荐。通过array数组自带的api来实现
```javascript
var arr = ["千古","宿敌","素颜"];
console.log(arr.join("|"));
```
结果:
![](http://img.smyhvae.com/20180126_1339.png)
### 练习2
题目将一个字符串数组的元素的顺序进行反转使用两种种方式实现。提示第i个和第length-i-1个进行交换。
答案:
方式1
```javascript
function reverse(array) {
var newArr = [];
for (var i = array.length - 1; i >= 0; i--) {
newArr[newArr.length] = array[i];
}
return newArr;
}
```
方式2算法里比较常见的方式
```javascript
function reverse(array){
for(var i=0;i<array.length/2;i++){
var temp = array[i];
array[i] = array[array.length-1-i];
array[array.length-1-i] = temp;
}
return array;
}
```
方式3数组自带的reverse方法
现在我们学习了数组自带的api我们就可以直接使用reverse()方法。
### 练习3
问题:针对工资的数组[1500,1200,2000,2100,1800]把工资超过2000的删除。
答案:
```javascript
var arr1 = [1500, 1200, 2000, 2100, 1800];
var arr2 = arr1.filter(function (ele, index, array) {
if (ele < 2000) {
return true;
}
return false;
})
console.log(arr1);
console.log(arr2);
```
结果:
![](http://img.smyhvae.com/20180126_1435.png)
### 练习4
问题:找到数组["c","a","z","a","x","a"]中每一个元素出现的次数。
分析这道题建议用json数据来做因为我们想知道a出现了几次c出现了几次x出现了几次。恰好`k:v .. k:v`这种键值对的形式就比数组方便很多了。
键值对的形式用key代表数组中的元素用value代表元素出现的次数。
略难,答案暂略。
### 练习5数组去重
问题:编写一个方法去掉一个数组中的重复元素。
分析:创建一个新数组,循环遍历,只要新数组中有老数组的值,就不用再添加了。
答案:
```javascript
// 编写一个方法 去掉一个数组的重复元素
var arr = [1,2,3,4,5,2,3,4];
console.log(arr);
var aaa = fn(arr);
console.log(aaa);
//思路:创建一个新数组,循环遍历,只要新数组中有老数组的值,就不用再添加了。
function fn(array){
var newArr = [];
for(var i=0;i<array.length;i++){
//开闭原则
var bool = true;
//每次都要判断新数组中是否有旧数组中的值。
for(var j=0;j<newArr.length;j++){
if(array[i] === newArr[j]){
bool = false;
}
}
if(bool){
newArr[newArr.length] = array[i];
}
}
return newArr;
}
```
## 我的公众号
想学习<font color=#0000ff>**代码之外的技能**</font>?不妨关注我的微信公众号:**千古壹号**id`qianguyihao`)。
扫一扫,你将发现另一个全新的世界,而这将是一场美丽的意外:
![](http://img.smyhvae.com/20190101.png)