目录
[1、instanceof 运算符](#1、instanceof 运算符)
3、Object.prototype.toString.call()
[4、constructor 属性](#4、constructor 属性)
前言:
我们在之前的学习中了解了对象是一组无序的属性和方法的集合,那一组有序的集合我们该叫什么?因此我们引出了数组的概念
一、数组的概念
数组是指一组有序数据 的集合,其中每个数据被称为元素,在数组中可以存放任意类型的元素,数组是将一组数据存储在单个变量名下的优雅方式。
数组是一个特殊的对象, 它和我们普通对象功能类似,也是用来存储一些值的,不同的是普通对象是使用字符串作为属性名的,而数组是使用数字作为索引操作元素,索引 :从0开始的整数就是索引,数组的存储性能比普通对象要好,所以在开发中, 我们经常使用数组来存储数据
二、数组的创建
数组的创建具有多种方式,下面我们介绍四种
1、使用构造函数来创建
使用构造函数 new Array() 来创建
javascript
let arr1= new Array ();
//给数组赋值,可以是任意类型
arr1[0]=10;
arr1[1]="jack";
arr1[2]=function(){
console.log("hello");
return("111");
}
arr1[3]={
name:"张三",
age:18,
sayHei:function(){
console.log("hai");
return "调用了";
}
}
//调用数组
console.log(arr1[2]());
console.log(arr1[3].sayHei());
2、使用构造函数(直接填充数组内容用逗号隔开)
javascript
let arr1 = new Array("hello", 123, function () { return 1 },)
console.log(arr1[2]());
3、使用构造函数(在括号里写初始长度)
javascript
let vrr2 = new Array(4);
vrr2[0] = 10;
vrr2[1] = 11;
vrr2[2] = 12;
// vrr2[3] = 15;
// vrr2[4] = 15;//超出的话长度就变成5了
console.log(vrr2);
4、使用字面量来创建
语法:[]
javascript
let arr1=[ //底层帮我们 new Array()
"jack",
18,
function(){
console.log("hello");
return 1;//不写return的话,就是可以调用函数但是函数并没有返回值,下面就有一个undefined
},
{
name:"张三"
},
[1,2,3,[4,5,6]]//套几层就是几维数组
]
// console.log(arr1[2]());
console.log(arr1[4][3][1]);
三、数组的基本操作
首先,数组具有索引(下标),是用来访问数组元素的序号(从0开始)
javascript
var arr=['孙悟空','猪八戒','沙和尚','唐僧']
索引号:0,1,2,3
1、读取数组中的元素
数组可以通过索引来访问(获取得到)、设置、修改对应的数组元素,我们可以通过"数组名[索引]"的形式来获取数组中的元素。如果读取不存在的索引,他不会报错,而会返回undefined
javascript
let arr1=["周一","周二","周三","周四","周五"];
console.log(arr1[0]);// 周一
console.log(arr1[4]);// 周五
2、修改数组元素值
语法:数组[索引]=值
javascript
arr[0] = 10;
arr[1] = 33;
arr[2] = 22;
无则创建添加,有则覆盖修改
3、修改length
如果修改的length大于原长度,则多出部分会空出来
如果修改的length小于原长度,则多出来的元素会被删除
4、删除数组元素
使用delete,被删除的索引会空出来,查找的话,返回undefined
javascript
let arr1 = new Array();
// 添加元素
arr1[0] = "jack";
arr1[1] = 18;
arr1[2] = function () {
console.log("hello");
};
arr1[3] = {
a: 1,
};
delete arr1[1];
console.log(arr1);
5、向数组的最后一个位置添加元素
语法:数组[数组.length]=值;
length是数组的长度,也就是数组的元素个数,这个值要比索引大1,因为索引从0开始
四、数组的检测
顾名思义,数组的检测就是来检测对象是否是一个数组,主要有以下四种方式
1、instanceof 运算符
我们之前使用它是在检测一个对象是否是一个类的实例:语法:对象 instanceof 构造函数
现在检测数组:语法:arr instanceof Array
当然,它的缺点依旧存在:由于所有对象都是Object的后代,在arr instanceof Object 也会返回true
2、Array.isArray()
用于确定传递的值是否是一个 Array。
语法:Array.isArray(value)
javascript
Array.isArray([1, 2, 3]); // true
Array.isArray({ foo: 123 }); // false
Array.isArray("foobar"); // false
Array.isArray(undefined); // false
3、Object.prototype.toString.call()
我们之前说过这是用来检测数据类型的通用方法,因此在这里依旧可以使用
javascript
console.log(Object.prototype.toString.call(arr)); //[object Array]
console.log(Object.prototype.toString.call(arr) === '[object Array]'); // true
它的返回值是[object Array],如果需要进行逻辑运算则要加一步全等的过程
4、constructor 属性
检查对象的构造函数是否为 Array
javascript
const arr = [1, 2, 3];
console.log(arr.constructor === Array); // true
constructor也有缺点:他的属性值可以被修改
javascript
arr.constructor=Object
console.log(arr.constructor===Object);//结果为true
五、数组的遍历
**遍历:**就是把数组中的每个元素从头到尾都访问一次(类似我们每天早上学生的点名)
遍历的方法有很多,下面我们介绍六种方式
1、for循环
javascript
let arr = ["red", "orange", "yellow", "green", "black"];
for(let i=0;i<arr.length;i++){
console.log(arr[i]);
}
这是最基础的for循环,可以实现遍历效果,但是存在一个问题,每次循环都会计算arr.length方法,这会影响效率。
2、优化版for循环
基于基础的for循环进行修改
javascript
let num=arr.length;
//最简单,将变量定义在外部
for(let i=0;i<num;i++){
console.log(arr[i]);
}
//将变量的赋值定义在循环内部
let num = arr.length;
for (let i = 0, num = arr.length; i < num; i++) {
//我们知道for循环变量在赋初值时只会执行一次
console.log(arr[i]);
}
3、for······in·····
我们在前面枚举对象中属性时曾用过,数组作为特殊的对象自然也可以使用
javascript
let arr = ["red", "orange", "yellow", "green", "black"];
for(let i in arr){
console.log(arr[i]);
}
4、for······of·····
用法和上面for······in·····一样,但它是数组专用的
javascript
for (let v of arr) {
console.log(v);
}
5、forEach()
这个方法需要一个函数作为参数,只支持IE8以上的浏览器,所以还是建议使用for循环来遍历
像这种函数,由我们创建,但是不由我们调用的,我们称为回调函数
数组中有几个元素函数就执行几次,每次执行时,浏览器会将遍历到的元素,以实参的形式传递进来,我们可以来定义行参,来读取这些内容(要几个值就定义几个就行)
浏览器会在函数中中传递了三个参数;
第一个参数:就是当前正在遍历的元素
第二个参数:就是当前正在遍历的元素的索引
第三个参数:就是当前正在遍历的数组
javascript
arr.forEach((item, index) => {
console.log(item);
});
6、map()
map()和forEach()很相似,不同的是map()会返回一个新的数组
javascript
let arr1 = arr.map((item, index, arr) => {
return (item += "!");//返回元素+!做区分
});
console.log(arr);
console.log(arr1);

六、冒泡排序
是一种算法,把一系列的数据按照一定的顺序进行排列显示(从小到大或从大到小)。
原理:
重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误,就把他们较换过来。
走访数列的工作是重复地进行,直到没有再需要交换,也就是该数列已经排序完成。
这个算法的名字由来是因为最小的元素会经由交换慢慢"浮"到数列的顶端
javascript
//基础双重for循环,就可以做到,但是有效率问题
let arr = [1, 3, 5, 2, 7, 4, 8]
for (let i = 0; i < arr.length; i++) {
for (let j = 0; j < arr.length; j++) {
let temp;
if (arr[j] > arr[j + 1]) {
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
console.log(arr);
//在上面的基础上减少了循环的次数,提高了效率
let arr = [1, 3, 5, 2, 7, 4, 8]
for (let i = 0; i < arr.length - 1; i++) {
//一共7个数,只要比6次,从0开始,所以-1
for (let j = 0; j < arr.length - i - 1; j++) {
// 外层一次循环就已经确定一个最大数了
let temp;
if (arr[j] > arr[j + 1]) {
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
console.log(arr);
七、数组的方法
1、常用的添加删除方法
|-----------|------------------------------|------------|
| 方法名 | 说明 | 返回值 |
| push() | 末尾添加一个或多个元素,修改原数组 | 并返回新数组的长度 |
| pop() | 删除数组最后一个元素,把数组长度减1,无参数,修改原数组 | 并返回删除的元素的值 |
| unshift() | 向数组的开头添加一个或更多元素,修改原数组 | 并返回新数组的长度 |
| shift() | 删除数组的第一个元素,数组长度减1 无参数,修改原数组 | 并返回删除的元素的值 |
1.1、push
该方法可以向数组的末尾中添加一个或者多个元素 ,并返回数组新的长度
可以将要添加的元素作为方法的参数传递,这样这些元素将会自动添加到元素的末尾
原数组会发生变化
javascript
let arr=["张三","李四","王五","赵六"]
arr[arr.length]="周七";
//我们之前是这样在最后增加元素的
arr.push("赵钱","孙李")
console.log(arr);
1.2、pop()
该方法可以删除数组的最后一个元素 ,一次就删除一个元素
pop()没有参数
将被删除的元素作为返回值返回
原数组会发生变化
javascript
arr.pop()
1.3、 unshift()
向数组开头添加一个或者多个元素,并返回新的数组长度
向前边插入元素后,其他的元素索引会依次调整
原数组会发生变化
javascript
let arr=["张三","李四","王五","赵六"]
arr[arr.length]="周七";//我们之前是这样在最后增加元素的
// arr.push("赵钱","孙李")
// arr.pop()
arr.unshift("Faker")
console.log(arr);

1.4、shift()
可以删除数组的第一个元素,一次就删除一个元素
shift()没有参数
被删除的元素作为返回值返回
原数组会发生变化
javascript
arr.shift();
2、其他常用数组方法
2.1、 slice()
可以用来从数组提取指定元素
不会改变元素原数组,而是将截取到的元素封装到一个新数组中返回
参数:
1:截取开始的位置的索引,包含开始索引
2:截取结束的位置的索引,不包含结束索引
第二个参数,可以省略不写,此时会截取从开始索引往后的所有元素
索引可以传递一个负值,如果传递一个负值,则从后往前计算
-1:倒数第一个,-2:倒数第二个
javascript
let arr = ["hell0", true, 1, 2, "你好", undefined, null, "问心"]
let res = arr.slice(6, 8);
// res=arr.slice(0) //深拷贝,数组复制一遍
// res = arr.slice(2,-2);// 1, 2, "你好", undefined
console.log(arr);
console.log(res);

2.2、splice()
可以用来删除数组中的指定元素
会影响到原数组,会将指定元素从原数组中删除,并将删除的元素作为返回值返回
参数:
第一个,表示开始位置的索引
第二个,表示删除的数量
第三个及以后...
可以传递一些新的元素,这些元素将会自动插入到
开始位置,索引前边
javascript
let arr = ["hell0", true, 1, 2, "你好", undefined, null, "问心"];
arr.splice(2, 2, 3, 4, 5);
console.log(arr);

2.3、indexOf
返回在数组中可以找到的一个给定元素的第一个索引,如果不存在,则返回-1
注意:它只返回第一个满足条件的索引号
语法:arr.indexOf(searchElement)
lastIndexOf
返回指定元素在数组中的最后一个索引,如果不存在,返回-1
javascript
var arr = ["red", "orange", "green", "yellow", "green"];
let res = arr.indexOf("green");
if (res !== -1) {
console.log("找到了");
}
//res=arr.lastIndexOf('green')//输出4
console.log(res);// 输出2
2.4、includes()
返回数组中是否含有给定的元素,有则true,无则false
javascript
var arr = ["red", "orange", "green", "yellow", "green"];
let res1 = arr.includes("green");
if (res1) {
console.log("找到了");
}
console.log(res1); //true
2.5、concat()
可以合并两个或多个数组,并将新的数组返回 ,也可以传其他数据类型 ,该方法不会对原数组产生影响
数组合并还可以使用扩展运算符: ...
javascript
var arr = ["孙悟空", "猪八戒"];
var arr2 = ["唐僧"];
var arr3 = ["嫦娥"];
// 数组合并:方式一
let res1 = arr.concat(arr2, arr3);
// 数组合并:方式二 扩展运算符 ...
let res2=[...arr,...arr2,...arr3];
console.log(res1);
console.log(res2);
2.6、join()
该方法可以讲数组转成一个字符串
该方法不会对原数组产生影响,而是将转换后的字符串作为结果返回
在join()中可以指定一个字符串作为参数,这个字符串将会成为数组中元素的连接符
如果不指定连接符,则默认使用",",作为连接符
javascript
var arr = ["孙悟空", "猪八戒", 1];
// 数组转字符串:方式一
let res = String(arr);
res = arr + "";
res = arr.toString();
//这三个是字符串的方法
let res = arr.join('%');
console.log(res); //孙悟空%猪八戒%1
2.7、split()
使用指定的分隔符字符串将一个String对象分割成子字符串数组,
以一个指定的分割字串来决定每个拆分的位置
javascript
var str = "red1,orange1,yellow1";
let res = str.split('1');
console.log(res); // ['red', ',orange', ',yellow', '']
2.8、reverse()
该方法用来反转数组(前边的去后边,后边的去前边)
该方法会直接修改原数组!
javascript
var arr = ["孙悟空", "猪八戒", 1];
let res = arr.reverse();
console.log(arr);
console.log(res);//[1, '猪八戒', '孙悟空']
2.9、sort()
可以用来对数组中的元素进行排序
会影响原数组,默认会按照Unicode编码进行排序
即使对纯数字的数组,使用sort()排序,也会按照Unicode编码进行排序
所以对数字排序时,可能会得到错误的结果,可以自己来指定排序的规则
可以在sort()添加回调函数,来制定排序规则,
回调函数中需要定义两个形参数,
浏览器将会分别使用数组中的元素作为实参去调用回调函数
使用哪个元素调用不确定,但是肯定的是在数组中,a一定在b前边
浏览器会根据回调函数的返回值来决定元素的顺序
如果返回一个大于0的值,则元素会交换位置
如果返回一个小于0的值,则元素位置不变
如果反回一个0,则认为两个元素相等,也不交换位置
如果需要升序,则返回a-b
如果需要降序排列,则返回b-a
javascript
// let arr = [1, 4, 2, 6, 7, 2, 3, 5];
// arr.sort();
let arr = ["11", "7", "3", "4", "8"];
// 自己制定排序规则
arr.sort((a,b) => {
// 升序 a-b
// return a - b;
// 降序 b-a
// return b - a;
// 随机排序 Math.random()返回一个0-1之间数
return Math.random() - 0.5; //返回值的正负概率分别为50%,故升降序排列是随机的
});
console.log(arr);
2.10、filter过滤
遍历数组,返回一个新数组 ,包含所有通过测试(回调函数返回 true)的元素,不改变原数组。
javascript
var list = [32, 93, 77, 53, 38, 87];
var resList = list.filter((item, index, array) => {
return item >= 60;
});
console.log(resList);
// 结果: [93, 77, 87] (只保留及格分数)
2.11、reduce求和
对数组每个元素执行回调函数,最终计算为一个单一值(可以是数字、字符串、对象甚至数组)。
javascript
var arr = [2, 3, 4, 5];
var sum = arr.reduce((prev, item, index, array) => {
return prev + item;
}, 0);
console.log(sum);
// 计算过程: (((0+2)+3)+4)+5 = 14