js数组
数组有哪些原生方法?
- 数组声明:new Array、字面量、Array.of
- 数组检测:Array.isArray、instanceof、原型链、Object.prototype.toString.call()、Array.prototype.isPrototypeOf
- 数组和字符串的转换方法:toString()、String()、toLocalString、join、split其中 join() 方法可以指定转换为字符串时的分隔符。
- 数组尾部操作的方法 pop() 和 push(),均改变原数组,push返回数组元素数量,pop返回弹出的元素
- 数组首部操作的方法 shift() 和 unshift() ,均改变原数组,unshift返回数组元素数量,shift返回弹出的元素
- 重排序的方法 reverse() 和 sort(),sort() 方法可以传入一个函数来进行比较,传入前后两个值,如果返回值为正数,则交换两个参数的位置。
- 数组连接的方法 concat() 、展开语法,返回的是拼接好的数组,不改变原数组。
- 数组截取办法 slice(),用于截取数组中的一部分元素返回,不改变原数组,返回截取的新数组
- 数组插入方法 splice(), 在任意位置添加、删除、替换,改变原数组,返回删除的元素
- 查找特定元素的方法,indexOf、 lastIndexOf 、includes、find、findIndex
- 迭代方法keys、values、entries、 every、some、filter、map 、reduce和 forEach 、for/in、for/of.
声明数组
1-Array.of
Array.of 与 new Array 不同是设置一个参数时不会创建空元素数组
let hd = Array.of(3);
console.log(hd); //[3]
let hda = new Array(3);
console.log(hda); //['','','']
2-Array.isArray
检测变量是否为数组类型
console.log(Array.isArray([1, "后盾人", "hdcms"])); //true
console.log(Array.isArray(9)); //false
类型转换
1-数组转换字符串
(1).toString()
大部分数据类型都可以使用.toString() 函数转换为字符串。
console.log(([1, 2, 3]).toString()); // 1,2,3
(2)函数 String
也可以使用函数 String 转换为字符串。
console.log(String([1, 2, 3]));
(3)join
使用join连接为字符串
console.log([1, 2, 3].join("-"));//1-2-3
2-Array.from
(1)使用Array.from可将类数组转换为数组,类数组指包含 length 属性或可迭代的对象。
- 第一个参数为要转换的数据,第二个参数为类似于
map函数的回调方法
let str = '后盾人';
console.log(Array.from(str)); //["后", "盾", "人"]
<body>
<button message="后盾人">button</button>
<button message="hdcms">button</button>
</body>
<script>
let btns = document.querySelectorAll('button');
console.log(btns); //包含length属性
Array.from(btns, (item) => {
item.style.background = 'red';
});
</script>
展开语法
数组合并,函数参数,节点转换
解构赋值
1-数组结构
let [name, url] = ['后盾人', 'houdunren.com'];
console.log(name); //后盾人
let [a, ...b] = ['后盾人', 'houdunren', 'hdcms'];
console.log(b); //[ 'houdunren', 'hdcms' ]
2-字符串解构
const [...a] = "houdunren.com";
console.log(a); //Array(13)
3-设置默认值
let [name, site = 'hdcms'] = ['后盾人'];
console.log(site); //hdcms
管理元素
| 语法名 | 元素位置 | 数组是否改变 | 返回值 |
|---|---|---|---|
| push | 从后添加 | 改变原数组 | 数组元素数量 |
| unshift | 从前添加 | 改变原数组 | 数组元素数量 |
| pop | 从后弹出 | 改变原数组 | 弹出的元素 |
| shift | 从前弹出 | 改变原数组 | 弹出的元素 |
| 中间元素 | |||
| fill | 中间添加 | 改变原数组 | 原数组 |
| slice | 截取元素 | 不改变原数组 | 截取的新数组 |
| splice | 在任意位置添加、删除、替换 | 改变原数组 | 删除的元素 |
对数组前后元素的管理
1-push
- 从后添加元素
- 改变原数组
- 返回值为数组元素数量
let arr = ["后盾人", "hdcms"];
console.log(arr.push(1, 2)); //4
console.log(arr); //[ '后盾人', 'hdcms', 1, 2 ]
2-unshift
- 从前添加元素
- 改变原数组
- 返回值为数组元素数量
let arr = ["后盾人", "hdcms"];
console.log(arr.unshift('向军大叔', 'houdunren')); //4
console.log(arr); //["向军大叔", "houdunren", "后盾人", "hdcms"]
3-pop
- 从末尾弹出
- 改变原数组
- 返回值为弹出的元素
let arr = ["后盾人", "hdcms"];
console.log(arr.pop()); //hdcms
console.log(arr); //["后盾人"]
4-shift
- 从前弹出
- 改变原数组
- 返回值为弹出的元素
let arr = ["后盾人", "hdcms"];
console.log(arr.shift()); //后盾人
console.log(arr); //["hdcms"]
对数组中间元素的管理
5-fill
第一个参数为填充的内容,第二个为从哪里开始添加,第三个为添加到那个位置
- 填充元素
- 改变原数组
- 返回值为原数组
let a = [1, 2, 3, "12"];
console.log(a.fill("后盾人", 2, 4)); //[ 1, 2, '后盾人', '后盾人' ]
6-slice
第一个参数为从哪里开始截取,第二个为截取的位置
- 截取元素
- 不改变原数组
- 返回值为截取的元素组成的新数组
let arr = [0, 1, 2, 3, 4, 5, 6];
console.log(arr.slice(1, 3)); // [1,2]
let arr = [0, 1, 2, 3, 4, 5, 6];
console.log(arr.slice()); //[0, 1, 2, 3, 4, 5, 6]
7-splice
使用 splice 方法可以在数组的任意位置添加、删除、替换数组中的元素
- 添加、删除、替换数组中的元素
- 改变原数组
- 返回值为删除的元素,没有删除的元素返回为空
let arr = [1, 2, 3, 4, 5];
let b = arr.splice(0, 2); //从第0个开始,截取几个元素 相当于删除
let c = arr.splice(0, 0, "hou"); //从第0个开始,不截取元素,添加一个元素 相当于添加
let d = arr.splice(0, 1, "hd"); //从第0个开始,截取1个元素,添加一个元素 相当于替换
console.log(arr, b, c, d); //[ 'hd', 3, 4, 5 ] [ 1, 2 ] [] [ 'hou' ]
清空数组
将数组值修改为[]可以清空数组,如果有多个引用时数组在内存中存在被其他变量引用。
let user = [{ name: "hdcms" }, { name: "后盾人" }];
let cms = user;
user = [];
console.log(user);
console.log(cms);
合并拆分
1-join
使用join连接成字符串
let arr = [1, "后盾人", "hdcms"];
console.log(arr.join('-')); //1-后盾人-hdcms 使用join可以指定转换的连接方式
2-split
split 方法用于将字符串分割成数组,类似join方法的反函数。
let price = "99,78,68";
console.log(price.split(",")); //["99", "78", "68"]
3-concat
concat方法用于连接两个或多个数组
let array = ["hdcms", "houdunren"];
let hd = [1, 2];
let cms = [3, 4];
console.log(array.concat(hd, cms)); //["hdcms", "houdunren", 1, 2, 3, 4]
// 也可以使用扩展语法实现连接
console.log([...array, ...hd, ...cms]);
4-copyWithin
使用 copyWithin 从数组中复制一部分到同数组中的另外位置。
const arr = [1, 2, 3, 4];
//array.copyWithin(target, start, end)
console.log(arr.copyWithin(2, 0, 2)); //[1, 2, 1, 2]
查找元素
1-indexOf
使用 indexOf 从前向后查找元素出现的位置,找到返回元素索引,如果找不到返回 -1。
let arr = [7, 3, 2, 8, 2, 6];
console.log(arr.indexOf('8')); // -1 indexOf 类似于===是严格类型约束。
console.log(arr.indexOf(2)); // 2 从前面查找2出现的位置
第二个参数用于指定查找开始位置
let arr = [7, 3, 2, 8, 2, 6];
//从第二个元素开始向后查找
console.log(arr.indexOf(2, 3)); //4
2-lastIndexOf
使用 lastIndexOf 从后向前查找元素出现的位置,如果找不到返回 -1。
let arr = [7, 3, 2, 8, 2, 6];
console.log(arr.lastIndexOf(2)); // 4 从后查找2出现的位置
3-includes
使用 includes 查找字符串返回值是布尔类型更方便判断
let arr = [7, 3, 2, 6];
console.log(arr.includes(6)); //true
4-find
find 方法找到后会返回第一次找到的值,不继续查找,如果找不到返回值为undefined
let arr = ["hdcms", "houdunren", "hdcms"];
let find = arr.find(function(item) {
return item == "hdcms";
});
console.log(find); //hdcms
使用includes等不能查找引用类型,因为它们的内存地址是不相等的,find 可以方便的查找引用类型
const user = [{ name: "李四" }, { name: "张三" }, { name: "后盾人" }];
const find = user.find(user => (user.name = "后盾人"));
console.log(find);
5-findIndex
findIndex 与 find 的区别是返回索引值,查找不到时返回 -1
let arr = [7, 3, 2, '8', 2, 6];
console.log(arr.findIndex(function (v) {
return v == 8; //findindex和indexOf不同的是findindex是==非严格类型约束。
})); //3
数组排序
1-reverse
反转数组顺序,改变原数组
let arr = [1, 4, 2, 9];
console.log(arr.reverse()); //[9, 2, 4, 1]
2-sort
- 返回负数 a 排在 b 前面,从小到大
- 返回正数 b 排在 a 前面,从大到小
- 返回 0 时不动
默认从小于大排序数组元素,改变原数组
let arr = [1, 4, 2, 9];
console.log(arr.sort()); //[1, 2, 4, 9]
使用排序函数从大到小排序,参数一与参数二比较,返回正数为降序负数为升序,改变原数组
let arr = [1, 4, 2, 9];
console.log(arr.sort(function (v1, v2) {
return v2 - v1;
})); //[9, 4, 2, 1]
循环遍历
1-forEach
forEach使函数作用在每个数组元素上,没有返回值。
let lessons = [
{ title: "媒体查询响应式布局", category: "css" },
{ title: "FLEX 弹性盒模型", category: "css" },
{ title: "MYSQL多表查询随意操作", category: "mysql" },
];
lessons.forEach((item, index, array) => {
console.log(item, index, array);
//item 每个数组元素
//index 每个索引
//array 原数组
});
2-for/in
遍历时的 key 值为数组的索引
let lessons = [
{title: '媒体查询响应式布局',category: 'css'},
{title: 'FLEX 弹性盒模型',category: 'css'},
{title: 'MYSQL多表查询随意操作',category: 'mysql'}
];
for (const key in lessons) {
console.log(key);
}
3-for/of
每次循环取其中的值。
let lessons = [
{ title: "媒体查询响应式布局", category: "css" },
{ title: "FLEX 弹性盒模型", category: "css" },
{ title: "MYSQL多表查询随意操作", category: "mysql" },
];
for (const item of lessons) {
console.log(item); // { title: "媒体查询响应式布局", category: "css" },
}
迭代器
const hd = ["houdunren", "hdcms"];
const keys = hd.keys();
console.log(keys.next());
console.log(keys.next());
1-keys
获取数组所有键
"use strict";
const arr = ["a", "b", "c", "后盾人"];
for (const key of arr.keys()) {
console.log(key); //0 1 2 3
}
2-values
获取数组的所有值
"use strict";
const arr = ["a", "b", "c", "后盾人"];
for (const value of arr.values()) {
console.log(value); //a , b , c , 后盾人
}
3-entries
返回数组所有键值对,将keys和values的方法结合
const arr = ["a", "b", "c", "后盾人"];
for (const [key, value] of arr.entries()) {
console.log(key, value);
}
数组扩展
1-every
every 用于递归的检测元素,要所有元素操作都要返回真结果才为真。
//查看班级中同学的 JS 成绩是否都及格
const user = [
{ name: "李四", js: 89 },
{ name: "马六", js: 65 },
{ name: "张三", js: 78 },
];
const result = user.every(function (item, index, arr) {
if (item.name == "李四") {
item.name = "李三";
}
return item.js >= 60;
});
console.log(result);
2-some
some 函数可以递归的检测元素,如果有一个返回 true,表达式结果就是真。
let words = ["后盾", "北京", "武汉"];
let title = "后盾人不断分享技术教程";
let state = words.some(function (item, index, array) {
console.log(title.indexOf(item));
return title.indexOf(item) >= 0;
});
if (state) console.log("标题含有违规关键词");
3-filter
使用 filter 可以过滤数据中元素,返回值为真被保留在新的数组,不会改变原数组。
let lessons = [
{ title: "媒体查询响应式布局", category: "css" },
{ title: "FLEX 弹性盒模型", category: "css" },
{ title: "MYSQL多表查询随意操作", category: "mysql" },
];
let cssLessons = lessons.filter(function (item, index, array) {
if (item.category.toLowerCase() == "css") {
return true;
}
});
console.log(cssLessons);
4-map
使用 map 映射可以在数组的所有元素上应用函数,用于映射出新的值,直接改变原数组
let lessons = [
{ title: "媒体查询响应式布局", category: "css" },
{ title: "FLEX 弹性盒模型", category: "css" },
{ title: "MYSQL多表查询随意操作", category: "mysql" },
];
lessons = lessons.map(function (item, index, array) {
item.title = `后盾人${item["title"]}`;
return item;
});
console.log(lessons);
5-reduce
函数参数说明如下
| 参数 | 说明 |
|---|---|
| prev | 上次调用回调函数返回的结果 |
| cur | 当前的元素值 |
| index | 当前的索引 |
| array | 原数组 |
//统计元素出现的次数
function countArrayELem(array, elem) {
return array.reduce((total, cur) => (total += cur == elem ? 1 : 0), 0);
}
let numbers = [1, 2, 3, 1, 5];
console.log(countArrayELem(numbers, 1)); //2
//取数组中的最大值
function arrayMax(array) {
return array.reduce(
(max, elem) => (max > elem ? max : elem), array[0]
);
}
console.log(arrayMax([1, 3, 2, 9]));
//取价格最高的商品
let cart = [
{ name: "iphone", price: 12000 },
{ name: "imac", price: 25000 },
{ name: "ipad", price: 3600 }
];
function maxPrice(array) {
return array.reduce(
(goods, elem) => (goods.price > elem.price ? goods : elem),
array[0]
);
}
console.log(maxPrice(cart));
//计算购物车中的商品总价
let cart = [
{ name: "iphone", price: 12000 },
{ name: "imac", price: 25000 },
{ name: "ipad", price: 3600 }
];
const total = cart.reduce(
(total, goods) => total += goods.price, 0
);
console.log(total); //40600
//获取价格超过 1 万的商品名称
let goods = [
{ name: "iphone", price: 12000 },
{ name: "imac", price: 25000 },
{ name: "ipad", price: 3600 }
];
function getNameByPrice(array, price) {
return array.reduce((goods, elem) => {
if (elem.price > price) {
goods.push(elem);
}
return goods;
}, []).map(elem => elem.name);
}
console.table(getNameByPrice(goods, 10000));
//使用 reduce 实现数组去重
let arr = [1, 2, 6, 2, 1];
let filterArr = arr.reduce((pre, cur, index, array) => {
if (pre.includes(cur) === false) {
pre = [...pre, cur];
}
return pre;
}, [])
console.log(filterArr); // [1,2,6]
原理
find 原理
下面使用自定义函数
let arr = [1, 2, 3, 4, 5];
function find(array, callback) {
for (const value of array) {
if (callback(value) === true) return value;
}
return undefined;
}
let res = find(arr, function(item) {
return item == 23;
});
console.log(res);
下面添加原型方法实现
Array.prototype.findValue = function(callback) {
for (const value of this) {
if (callback(value) === true) return value;
}
return undefined;
};
let re = arr.findValue(function(item) {
return item == 2;
});
console.log(re);
排序原理
let arr = [1, 5, 3, 9, 7];
function sort(array, callback) {
for (const n in array) {
for (const m in array) {
if (callback(array[n], array[m]) < 0) {
let temp = array[n];
array[n] = array[m];
array[m] = temp;
}
}
}
return array;
}
arr = sort(arr, function(a, b) {
return a - b;
});
console.table(arr);