后盾人JS -- JS数组挖掘(成年篇)
自定义find原型方法实现
<!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>
function find(array,callback){
for(const value of array){
if(callback == value)
{
return value
}
}
return undefined
}
let arr = [1,2,3,4,5]
console.log(find(arr,2))
</script>
</body>
</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>
Array.prototype.findValue = function(callback){
for(const value of this){
if(callback(value)) return value
}
return undefined
}
let arr = [1,2,3,4,5]
const res = arr.findValue(function(item){
return item == 2
})
console.log(res)
</script>
</body>
</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 arr = [5,6,1,8,9,3]
arr = arr.sort(function(a,b){
//-1 从小到大 1 从大到小
return a-b
})
console.table(arr)
</script>
</body>
</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 cart = [
{name:"iphone" ,price:12000},
{name:"imac" , price:18000},
{name:"ipad",price:3200}
]
cart = cart.sort(function(a,b){
return a.price - b.price
})
console.table(cart)
</script>
</body>
</html>
sort排序算法原理实现
<!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 arr = [1, 5, 3, 6, 4]
//sort
function sort(array, callback) {
for (const n in array) {
for (const m in array) {
if (callback(array[n], array[m]) < 0) {
const temp = array[n]
array[n] = array[m]
array[m] = temp
}
}
}
return array
}
console.log(sort(arr, function (a, b) {
return b - a
}))
</script>
</body>
</html>
循环操作中引用类型使用技巧
要注意的是值类型的改变不会影响原来数组,但是引用类型会
forEach循环方法使用
<!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 lessons = [
{title:"媒体查询响应式布局",category:"css"},
{title:"FLEX弹性盒模型",category:"css"},
{title:"增删改查",category:"mysql"}
]
lessons.forEach(function(item,index,lessons){
item.title = item.title.substr(0,2)
})
console.log(lessons)
</script>
</body>
</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>
<style>
.disable{
color: #ddd;
}
</style>
<ul>
<li>hdcms</li>
<li>houdunren</li>
</ul>
<script>
let lis = document.querySelectorAll("ul li")
lis.forEach(function(item){
item.addEventListener("click",function(){
this.classList.toggle("disable")
})
})
</script>
</body>
</html>
iterator迭代器方法玩转数组
<!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 arr = ["hdcms","houdunren"]
let values = arr.values()
while(({value,done}=values.next()) && done ===false)
{
console.log(value)
}
</script>
</body>
</html>
这是一种迭代对象的方法
使用for of方法迭代:
<!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 arr = ["hdcms","houdunren"]
for(const value of arr.values()){
console.log(value)
}
</script>
</body>
</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 arr = ["hdcms","houdunren"]
let entries = arr.entries()
console.log(entries.next())
</script>
</body>
</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 arr = ["hdcms","houdunren"]
for(const[key,value]of arr.entries()){
console.log(value)
}
</script>
</body>
</html>
every与some这么用的
再来看一些高效处理数组的方法
<!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 arr = ['hdcms','houdunren']
let status = arr.every(function(value,index,arr){
console.log(value)
return true
})
</script>
</body>
</html>
every可以这么用,当所有都为真的时候才返回真,而some是有一个是真的就是真的
使用的格式是一样的
filter过滤元素使用
<!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 lessons = [
{title:"媒体响应式布局",category:"css"},
{title:"FLEX弹性盒模型",category:"css"},
{title:"MYSQL多表查询随意操作",category:"mysql"},
]
const cssLessons = lessons.filter(function(lesson){
return lesson['category'] == 'css'
})
console.table(cssLessons)
</script>
</body>
</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 hd = [1, 2, 3, 4]
function filter(array, callback) {
let newArray = []
for (const value of array) {
if (callback(value) === true) {
newArray.push(value)
}
}
return newArray
}
console.log(filter(hd,function(value){
return value>2
}))
</script>
</body>
</html>
map映射数组与引用类型处理技巧
映射可以对数组进行二次操作:
<!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 lessons = [
{title:"媒体查询响应式布局",category:"css"},
{title:"FLEX弹性盒模型",category:"css"},
{title:"MYSQL多表查询随意操作",category:"mysql"}
]
let hd = lessons.map(function(value){
return{
title:value.title,
category:value.category,
click:100
}
})
console.table(hd)
console.table(lessons)
// let arr = ["hdcms","houdunren"]
// arr.map(function(value,index,arr){
// console.log(index)
// })
</script>
</body>
</html>
超好用的reduce方法详解
reduce
是 JavaScript 中数组的一个高阶方法,它接收一个回调函数和一个可选的初始值作为参数,将数组中的元素通过该回调函数进行组合或累积操作,最终返回一个单一的值
字符串拼接:
let words = ['Hello', 'World', '!'];
let sentence = words.reduce((accumulator, currentValue) => accumulator + " " + currentValue);
console.log(sentence); // 输出 "Hello World!
写一个统计数据出现几次的函数:
<!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 arr = [1, 2, 3, 1, 1]
function arrayCount(array, item) {
return array.reduce(function (total, cur) {
total += item == cur ? 1 : 0
return total
}, 0)
}
console.log(arrayCount(arr, 1))
</script>
</body>
</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 cart = [
{ name: "iphone", price: 12000 },
{ name: "imac", price: 25000 },
{ name: "ipad", price: 3600 }
]
function maxPric(goods) {
return cart.reduce(function (pre, cur) {
return pre.price > cur.price ? pre : cur
})
}
console.log(maxPric(cart))
</script>
</body>
</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 cart = [
{ name: "iphone", price: 12000 },
{ name: "imac", price: 25000 },
{ name: "ipad", price: 3600 }
]
function sum(goods){
return goods.reduce(function(total,cur){
return (total += cur["price"])
},0)
}
console.log(sum(cart))
</script>
</body>
</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 cart = [
{ name: "iphone", price: 12000 },
{ name: "imac", price: 25000 },
{ name: "ipad", price: 3600 }
]
function getNameByPrice(goods, price) {
return goods.reduce(function (arr, cur) {
if (cur.price > price) {
arr.push(cur)
}
return arr
}, []).map(function(item){
return item.name
})
}
console.table(getNameByPrice(cart, 10000))
</script>
</body>
</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 array = [1, 2, 3, 3, 1, 4, 2]
let newArr = array.reduce(function (arr, cur) {
if (arr.includes(cur) === false) {
arr.push(cur)
}
return arr
}, [])
console.log(newArr)
</script>
</body>
</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 cart = [
{ name: "iphone", price: 12000 },
{ name: "imac", price: 25000 },
{ name: "ipad", price: 3600 },
{ name: "iphone", price: 12000 }
]
function filterGoods(goods){
return goods.reduce(function(arr,cur){
let find = arr.find(function(v){
return v.name == cur.name
})
if(!find) arr.push(cur)
return arr
},[])
}
console.table(filterGoods(cart))
</script>
</body>
</html>
炫酷的文字LOGO效果元素构建
<!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>
<div>houdunren.com</div>
<script>
const div = document.querySelector('div');
// 使用 forEach 遍历字符数组
[...div.textContent].reduce(function (pre, cur, index) {
pre == index && (div.innerHTML = " ")
console.log(pre, cur, index);
let span = document.createElement("span")
span.innerHTML = cur
div.appendChild(span)
span.addEventListener("mouseover",function(){
this.classList.add("color")
})
}, 0);
</script>
</body>
</html>
为LOGO添加关键帧动画
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{
padding: 0;
margin: 0;
}
body{
width: 100vh; /*视口大小*/
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
background-color: chartreuse;
}
div{
font-size: 5em;
font-weight: bold;
text-transform: uppercase; /*大写*/
color: cornflowerblue;
text-align: center;
}
div>span{
position: relative;
display: inline-block;
}
.color{
animation-name: color;
animation-duration: 1s;
animation-iteration-count: 2;
animation-timing-function: linear;
animation-direction: alternate;
}
@keyframes color{ /*添加关键帧*/
50%{
color: darkorange;
transform: scale(2);
}
to{
color:violet;
transform: scale(0.5);
}
}
</style>
</head>
<body>
<div>houdunren.com</div>
<script>
const div = document.querySelector('div');
// 使用 forEach 遍历字符数组
[...div.textContent].reduce(function (pre, cur, index) {
pre == index && (div.innerHTML = " ")
console.log(pre, cur, index);
let span = document.createElement("span")
span.innerHTML = cur
div.appendChild(span)
span.addEventListener("mouseover",function(){
this.classList.add("color")
})
}, 0);
</script>
</body>
</html>
有个问题是这个只能动画一次,有缺陷,所以还要改
监听animationend事件移动动画类
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{
padding: 0;
margin: 0;
}
body{
width: 100vh; /*视口大小*/
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
background-color: chartreuse;
}
div{
font-size: 5em;
font-weight: bold;
text-transform: uppercase; /*大写*/
color: cornflowerblue;
text-align: center;
}
div>span{
position: relative;
display: inline-block;
}
.color{
animation-name: color;
animation-duration: 1s;
animation-iteration-count: 2;
animation-timing-function: linear;
animation-direction: alternate;
}
@keyframes color{ /*添加关键帧*/
50%{
color: darkorange;
transform: scale(1.5);
}
to{
color:violet;
transform: scale(0.5);
}
}
</style>
</head>
<body>
<div>houdunren.com</div>
<script>
const div = document.querySelector('div');
// 使用 forEach 遍历字符数组
[...div.textContent].reduce(function (pre, cur, index) {
pre == index && (div.innerHTML = " ")
console.log(pre, cur, index);
let span = document.createElement("span")
span.innerHTML = cur
div.appendChild(span)
span.addEventListener("mouseover",function(){
this.classList.add("color")
})
span.addEventListener('animationend',function(){
this.classList.remove("color")
})
}, 0);
</script>
</body>
</html>
至此数组相关操作全部结束捏