什么是数组
- 数组就是专门用于存储一组数据的
- 数组(
Array
)不是基本数据类型, 是引用数据类型(对象类型)
创建数组
通过构造函数创建数组
let 变量名称 = new Array(size); // 创建一个指定大小数组
let 变量名称 = new Array(); // 创建一个空数组
let 变量名称 = new Array(data1, data2, ...); // 创建一个带数据的数组
通过字面量创建数组
let 变量名称 = []; // 创建一个空数组
let 变量名称 = [data1, data2, ...]; // 创建一个空数组
操作数据
- 往数组中存储数据
变量名称[索引号] = 需要存储的数据;
- 从数组中获取存储的数据
变量名称[索引号];
数组的注意点
- 和其它编程语言不同,如果数组对应的索引中没有存储数据, 默认存储的就是
undefined
,其它编程语言中默认保存的是垃圾数据或者0 - 和其它编程语言不同,JavaScript中访问了数组中不存在的索引不会报错, 会返回
undefined
,其它编程语言一旦超出索引范围就会报错或者返回脏数据 - 和其它编程语言不同, 当JavaScript中数组的存储空间不够时数组会自动扩容,其它编程语言中数组的大小是固定的
- 和其它编程语言不同, JavaScript的数组可以存储不同类型数据,在其它编程语言中数组只能存储相同类型数据(要么全部都是字符串, 要么全部都是数值等)
- 和其它编程语言不同, JavaScript中数组分配的存储空间不一定是连续的,其它语言数组分配的存储空间都是连续的, JavaScript数组是采用"哈希映射"方式分配存储空间
- 在浏览器中各大浏览器也对数组分配存储空间进行了优化
- 如果存储的都是相同类型的数据, 那么会尽量分配连续的存储空间
- 如果存储的不是相同的数据类型, 那么就不会分配连续的存储空间
数组的遍历
数组的遍历就是依次取出数组中存储的所有数据
let arr = ["a", "b", "c"];
for(let i = 0; i < arr.length; i++){
console.log(arr[i]);
}
数组的解构赋值
解构赋值是ES6中新增的一种赋值方式
let arr = [1, 3, 5];
let [a, b, c] = arr;
console.log("a = " + a); // a = 1
console.log("b = " + b); // b = 3
console.log("c = " + c); // c = 5
- 在数组的解构赋值中,等号左边的格式必须和等号右边的格式一模一样,才能完全解构
// let [a, b, c] = [1, 3, [2, 4]];
let [a, b, [c, d]] = [1, 3, [2, 4]]
console.log("a = " + a);
console.log("b = " + b);
console.log("c = " + c);
console.log("d = " + d);
- 在数组的解构赋值中,左边的个数可以和右边的个数不一样,右边的个数可以和左边的个数不一样,解构不到的赋值为
undefined
let [a, b] = [1, 3, 5];
console.log("a = " + a);
console.log("b = " + b);
- 在数组的解构赋值中,如果右边的个数和左边的个数不一样, 那么我们可以给左边指定默认值
let [a, b = 666, c = 888] = [1];
console.log("a = " + a);
console.log("b = " + b);
console.log("c = " + c);
- 在数组的解构赋值中, 如果左边的个数和右边的个数不一样, 那么如果设置默认值会被覆盖
let [a, b = 666] = [1, 3, 5];
console.log("a = " + a);
console.log("b = " + b);
- 在数组的解构赋值中, 还可以使用ES6中新增的扩展运算符
...
来打包剩余的数据,如果使用了扩展运算符, 那么扩展运算符只能写在最后
let [a, ...b] = [1, 3, 5];
console.log("a = " + a);
console.log(b);
数组的增删改查
以下面这个数组为例
let arr = ["a", "b", "c"];
- 获取数组中索引为1的那个数据
console.log(arr[1]);
- 将索引为1的数据修改为
m
(改)
arr[1] = "m";
console.log(arr);
- 将索引为1的数据修改为
d
, 索引为2的修改为e
// 方法一
arr[1] = "d";
arr[2] = "e";
console.log(arr);
// 方法二
/*
splice() 方法
参数1: 从什么位置开始
参数2: 需要替换多少个元素
参数3开始: 新的内容
*/
arr.splice(1, 2, "d", "e")
console.log(arr);
- 在数组最后添加一条数据 (增)
// 方法一
arr[3] = "d";
console.log(arr);
// 方法二
// push方法可以在数组的最后新增一条数据, 并且会将新增内容之后数组当前的长度返回给我们
let res = arr.push("d");
console.log(res);
console.log(arr);
- 在数组最后添加两条数据 (增)
// 方法一
arr.push("d");
arr.push("e");
// 方法二
// 数组的push方法可以接收1个或多个参数
arr.push("d", "e");
console.log(arr);
- 在数组最前面添加一条数据 (增)
// unshift方法和push方法一样, 会将新增内容之后当前数组的长度返回给我们
let res = arr.unshift("m")
console.log(res);
console.log(arr);
- 在数组最前面添加两条数据 (增)
// 方法一
arr.unshift("m");
arr.unshift("w");
// 方法二
// unshift方法和push方法一样, 可以接收1个或多个参数
arr.unshift("m", "w");
console.log(arr);
- 删除数组最后一条数据 (删)
// 数组的pop方法可以删除数组中的最后一条数据, 并且将删除的数据返回给我们
let res = arr.pop();
console.log(res);
console.log(arr);
- 删除数组最前面一条数据 (删)
// 数组的shift方法可以删除数组中的最前面一条数据, 并且将删除的数据返回给我们
let res = arr.shift();
console.log(res);
console.log(arr);
- 删除数组中索引为1的数据 (删)
/*
splice也可以用来删除某个元素
参数1: 从什么位置开始
参数2: 需要删除多少个元素
*/
arr.splice(1, 1);
console.log(arr);
- 删除数组中除了第0条以外的所有数据 (删)
arr.splice(1,are.length - 1);
console.log(arr);
数组常用方法
- 清空数组
let arr = [1, 2, 3, 4, 5];
// 方法一
arr = [];
// 方法二
arr.length = 0;
// 方法三
arr.splice(0, arr.length)
console.log(arr);
- 将数组转换为字符串
let arr = [1, 2, 3, 4, 5];
let str = arr.toString();
console.log(str);
console.log(typeof str);
- 将数组转换成指定格式字符串
let arr = [1, 2, 3, 4, 5];
// join方法默认情况下如果没有传递参数, 就是调用toString();
// join方法如果传递了参数, 就会将传递的参数作为元素和元素的连接符号
let str = arr.join("+");
console.log(str);
console.log(typeof str);
- 将两个数组拼接为一个数组
let arr1 = [1, 3, 5];
let arr2 = [2, 4, 6];
// 数组不能够使用加号进行拼接, 如果使用加号进行拼接会先转换成字符串再拼接
let res = arr1 + arr2;
console.log(res);
console.log(typeof res);
// concat()可以用于数组的拼接,而且不会修改原有的数组, 会生成一个新的数组返回给我们
let res = arr1.concat(arr2);
console.log(res);
console.log(typeof res);
// ES6中扩展运算符可用于数组的拼接
// 扩展运算符在解构赋值中(等号的左边)表示将剩余的数据打包成一个新的数组
// 扩展运算符在等号右边,那么表示将数组中所有的数据解开,放到所在的位置
// 不会修改原有的数组, 会生成一个新的数组返回给我们
// 企业开发中推荐使用扩展运算符对数组进行拼接
let res = [...arr1, ...arr2];
console.log(res);
console.log(typeof res);
- 将数组中的内容进行反转
let arr = [1, 2, 3, 4, 5];
// reverse()可以对数组进行反转
// 会修改原有的数组
let res = arr.reverse();
console.log(res);
console.log(arr);
- 截取数组中指定范围内容
let arr = [1, 2, 3, 4, 5];
// slice方法是包头不包尾(包含起始位置, 不包含结束的位置)
let res = arr.slice(1, 3)
console.log(res); // 2,3
console.log(arr);
- 查找元素在数组中的位置
let arr = [1, 2, 3, 4, 5];
// indexOf方法如果找到了指定的元素, 就会返回元素对应的位置
// indexOf方法如果没有找到指定的元素, 就会返回-1
// indexOf方法默认是从左至右的查找, 一旦找到就会立即停止查找
// lastIndexOf方法默认是从右至左的查找, 一旦找到就会立即停止查找
let res = arr.indexOf(3);
console.log(res); // 2
let arr = [1, 2, 3, 4, 5, 3];
// indexOf方法也可以接受两个参数
// 参数1: 需要查找的元素
// 参数2: 从什么位置开始查找
let res = arr.lastIndexOf(3, 4);
console.log(res); // 5
- 判断数组中是否包含某个元素
let arr = [1, 2, 3, 4, 5];
// 可以通过indexOf和lastIndexOf的结果, 判断是否是-1即可
let res = arr.indexOf(8);
let res = arr.lastIndexOf(8);
console.log(res);
// ES6中可以通过includes() 方法查找
let res = arr.includes(4); // true
let res = arr.includes(8); // false
console.log(res);
- 字符串的split方法可以根据传入的参数切割字符串, 转换成一个数组之后返回
let str = '1,2,3,4,5';
let res = str.split(',');
console.log(res); // ["1", "2", "3", "4", "5"]
- 设置数组中所有元素的值为指定的数据
let arr = [1,2,3,4,5];
arr.fill(0);
console.log(arr); // [0, 0, 0, 0, 0]
二维数组
二维数组就是数组的每一个元素又是一个数组
操作二维数组
- 从二维数组中获取数据
// 数组名称[二维数组索引]; 得到一个一维数组
// 数组名称[二维数组索引][一维数组索引]; 得到一维数组中的元素
let arr = [[1, 3], [2, 4]];
let arr1 = arr[0]; // [1,3]
let ele = arr[0][1]; // 3
- 往二维数组中存储数据
// 数组名称[二维数组索引] = 一维数组;
// 数组名称[二维数组索引][一维数组索引] = 值;
// 在定义二维数组的时候, 将来需要存储多少个一维数组, 就写上多少个[]即可
let arr = [[],[]];
arr[0] = [1, 3];
arr[1][0] = 2;
console.log(arr);
二维数组的遍历
let arr = [[1, 3], [2, 4]];
for(let i = 0; i < arr.length; i++){
let subArray = arr[i];
// console.log(subArray);
for(let j = 0; j < subArray.length; j++){
console.log(subArray[j]);
}
}
数组高级API
数组的遍历
- 利用传统循环遍历数组
let arr = [1, 3, 5, 7, 9];
for (let i = 0; i < arr.length; i++){
console.log(arr[i]);
}
- 利用
for-in
循环遍历数组
let arr = [1, 3, 5, 7, 9];
for (let key in arr){
console.log(arr[key]);
}
// 在企业开发中不推荐使用for-in循环来遍历数组
// for-in循环是专门用于遍历对
// for-in循环就是专门用于遍历无序的东西
- 利用ES6中的
for-of
循环遍历数组
let arr = [1, 3, 5, 7, 9];
for (let value of arr){
console.log(value);
}
- 利用Array对象的
forEach
方法来遍历数组
let arr = [1, 3, 5, 7, 9];
// forEach方法会自动调用传入的函数
// 每次调用都会将当前遍历到的元素和当前遍历到的索引和当前被遍历的数组传递给这个函数
arr.forEach(function (currentValue, currentIndex, currentArray) {
// console.log(currentValue, currentIndex, currentArray);
console.log(currentValue);
});
- 自定义实现遍历
let arr = [1, 3, 5, 7, 9];
Array.prototype.myForEach = function (fn){
for (let i = 0; i < this.length; i++){
fn(this[i],i,this);
}
};
arr.myForEach(function (value,index,array) {
console.log(value, index, array);
})
数组元素的查找
- 数组的
findIndex
方法,定制版的indexOf
,找到返回索引,找不到返回-1
let arr = [3, 2, 6, 7, 6];
let index = arr.findIndex(function (value,index,array) {
if (value === 6){
return true;
}
});
console.log(index); // 2
- 数组的
find
方法,如果找到了就返回找到的元素,如果找不到就返回undefined
let arr = [3, 2, 6, 7, 6];
let value = arr.find(function (value,index,array) {
if (value === 6){
return true;
}
});
console.log(value); // 6
数组的过滤与映射
- 数组的
filter
方法,过滤一个数组,将满足条件的元素添加到一个新的数组中
let arr = [1,2,3,4,5,6];
let newArray = arr.filter(function (value,index,array) {
if (value % 2 === 0){
return true;
}
});
console.log(newArray); // [2, 4, 6]
- 数组的
map
方法,将满足条件的元素映射到一个新的数组中
let arr = [1,2,3,4,5,6];
let newArray = arr.map(function (value, index, array) {
return value * value;
});
console.log(newArray); // [1, 4, 9, 16, 25, 36]
删除数组元素
遍历的同时删除数组中所有元素
- 通过
splice
方法删除
let arr = [1, 2, 3, 4, 5];
// 通过splice删除元素后,会改变数组的长度,所以需要单独保存一份
let len = arr.length;
// 通过splice删除元素后,后面的元素会自动向前移动,补全空缺位置
// 所以需要从后往前删除
for (let i = len -1;i >= 0; i--){
arr.splice(i, 1);
}
console.log(arr); // []
- 通过
delete
删除
for(let i = 0; i < arr.length; i++){
console.log(arr.length);
// 通过delete来删除数组中的元素, 数组的length属性不会发生变化,也不会补全空缺位置
delete arr[i];
}
console.log(arr);
数组排序方法
- 数组元素是字符串类型
let arr = ["c", "a", "b"];
// arr.sort();
// console.log(arr); // ["a", "b", "c"]
/*
如果 compareFunction(a, b) 小于 0 ,那么 a 会被排列到 b 之前;
如果 compareFunction(a, b) 等于 0 , a 和 b 的相对位置不变。
如果 compareFunction(a, b) 大于 0 , b 会被排列到 a 之前
注意点: 如果元素是字符串类型, 那么比较的是字符串的Unicode编码
*/
arr.sort(function (a,b) {
if (a > b){
return -1;
}else if(a < b){
return 1;
}else{
return 0;
}
});
console.log(arr); // ["c", "b", "a"]
- 数组元素是数值类型
let arr = [3,4,1,0,9,2];
// arr.sort(); // 默认从小到大
arr.sort(function (a,b) {
// return a - b; // 从小到打
return b - a; // 从大到小
});
console.log(arr);
选择排序
let arr = [1,-4,5,0,9,22,-10];
console.log(arr);
for (let i = 0; i < arr.length; i++){
for (let j = i; j < arr.length; j++){
if (arr[i] > arr[j+1]){
let temp = arr[i];
arr[i] = arr[j+1];
arr[j+1] = temp;
}
}
}
console.log(arr);
let brr = ["1234", "21", "54321", "123", "6"];
brr.sort(function (str1,str2) {
// return str1.length - str2.length;
return str2.length - str1.length;
});
console.log(brr);
- 对象的排序
let students = [
{name: "zs", age: 34},
{name: "ls", age: 18},
{name: "ww", age: 22},
{name: "mm", age: 28},
];
students.sort(function (o1,o2) {
return o1.age - o2.age;
});
console.log(students);
/*
0: {name: "ls", age: 18}
1: {name: "ww", age: 22}
2: {name: "mm", age: 28}
3: {name: "zs", age: 34}
*/
字符串常用方法
在JavaScript中字符串可以看做一个特殊的数组, 所以大部分数组的属性/方法字符串都可以使用
- 获取字符串长度
let str = "abcd";
console.log(str.length); // 4
- 获取某个字符
let str = "abcd";
let ch1 = str[1]; // 仅支持高级浏览器
let ch2 = str.charAt(1); // 大部分浏览器都支持,推荐使用
console.log(ch1); // b
console.log(ch2); // b
- 字符串查找
let str = "vavcd";
let index1 = str.indexOf("v");
let index2 = str.lastIndexOf("v");
console.log(index1); // 0
console.log(index2); // 2
let res = str.includes('p');
console.log(res); // false
- 拼接字符串
let str1 = "hello ";
let str2 = "world";
let str3 = str1 + str2; // 推荐
let str4 = str1.concat(str2);
console.log(str3); // hello world
console.log(str4); // hello world
- 截取子串
let str = "abcdef";
// 下标1开始截取到下标3结束,不包括下标3
let subStr1 = str.slice(1, 3);
// 下标1开始截取到下标3结束,不包括下标3
let subStr2 = str.substring(1, 3);
// 下标1开始截取3个元素
let subStr3 = str.substr(1, 3);
console.log(subStr1); // bc
console.log(subStr2); // bc
console.log(subStr3); // bcd
- 字符串切割
let str = "1-3-5";
let arr = str.split("-");
console.log(arr);
- 判断是否以指定字符串开头或以指定字符串结尾 ES6
let str = "www.jianshu.com";
let result1 = str.startsWith("www");
console.log(result1); // true
let result2 = str.endsWith('com');
console.log(result2); // true
- 字符串替换
let str = 'abc';
let res = str.replace('c','m');
console.log(str);
console.log(res);
- 字符串模板
let str = `hello`;
console.log(str); // hello
console.log(typeof str); // string
let str1 = "\n" +
" - 我是第1个li
\n" +
" - 我是第2个li
\n" +
" - 我是第3个li
\n" +
"
";
// 以上代码可用以下代码代替
let str2 = `
- 我是第1个li
- 我是第2个li
- 我是第3个li
`;
let name = 'Jason';
let age = 24;
let str1 = "我的名字是" + name + ",我的年龄是" + age;
let str2 = `我的名字是${name},我的年龄是${age}`;
console.log(str1); // 我的名字是Jason,我的年龄是24
console.log(str2); // 我的名字是Jason,我的年龄是24
冒泡排序
let arr = [1,-4,5,0,9,22,-10];
console.log(arr);
for (let i = 0;i < arr.length; i++){
for (let j = 0;j < arr.length - i; j++){
if (arr[j] > arr[j+1]){
let temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
console.log(arr);