1. 数组常用方法
1.1 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>
// 过滤数组,返回满足筛选条件的新数组
const arr = [10, 20, 20, 30, 40]
// 过滤出大于20的元素
const newArr1 = arr.filter((el, index) => {
return el > 20
})
console.log(newArr1) // [30, 40]
// 过滤出等于20的元素
const newArr2 = arr.filter((el, index) => {
// return el = 20
// 上行写法错误,返回arr整个数组(=是赋值,==判断值,===判值和数据类型)
return el === 20
})
console.log(newArr2) // [20, 20]
</script>
</body>
</html>
1.2 find 返回符合条件的第一个元素
1.3 findIndex 返回符合条件的第一个元素的索引值
<!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>
const goods = [
{
name: '小米',
price: 1999
},
{
name: '华为',
price: 4999
},
{
name: '苹果',
price: 9999
},
{
name: '华为',
price: 6999
},
]
// find:返回符合条件的第一个元素值,没有则返回 undefined
const obj1 = goods.find(el => el.name === '华为')
console.log(obj1) // {name: '华为', price: 4999}
const obj2 = goods.find(el => el.name === 'VIVO')
console.log(obj2) // undefined
// findIndex:返回满足条件的第一个元素的索引,找不到则返回-1
const index1 = goods.findIndex(el => el.name === '华为')
console.log(index1) // 1
const index2 = goods.findIndex(el => el.name === 'VIVO')
console.log(index2) // -1
const index3 = goods.findIndex(el => el.name === '苹果')
console.log(index3) // 2
</script>
</body>
</html>
1.4 every 判断元素是否全部符合条件
1.5 some 判断是否有元素符合条件
1.6 reverse 反转数组
<!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>
const arr = [10, 20, 30, 5]
/* every(重点): 检测数组所有元素是否都符合指定条件,
如果所有元素都通过检测返回true,否则返回false */
const flag1 = arr.every(el => el >= 5)
console.log(flag1) // true
const flag2 = arr.every(el => el >= 8)
console.log(flag2) // false
/* some:检测数组中的元素是否满足指定条件,
如果数组中有元素满足条件返回true,否则返回false */
const flag3 = arr.some(el => el >= 24)
console.log(flag3) // true
const flag4 = arr.some(el => el >= 40)
console.log(flag4) // false
// reverse:反转数组,且会修改原数组
const arr1 = [10, 20, 30, 5]
console.log(arr1) // [10, 20, 30, 5]
const arr2 = arr1.reverse()
console.log(arr1, arr2) // [5, 30, 20, 10] [5, 30, 20, 10]
</script>
</body>
</html>
1.7 案例1_学成在线
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>学成在线</title>
<link rel="stylesheet" href="./iconfont/iconfont.css">
<link rel="stylesheet" href="./css/base.css">
<link rel="stylesheet" href="./css/index.css">
</head>
<body>
<div class="course wrapper">
<div class="info">
<div class="avatar">
<img src="./uploads/logo.avif" alt="">
<span class="bili-avatar-icon"></span>
</div>
<p class="desc">
<a class="user-name" href="https://space.bilibili.com/37974444" target="_blank">黑马程序员</a>
<span>传智教育旗下官方账号</span>
</p>
</div>
<div class="search">
<p class="line">
<span class="tip">筛 选</span>
<a href="javascript:;" onclick="allVue()">查找所有Vue课程</a>
<a href="javascript:;" onclick="find5K()">查找最先超过5K学习人数的课程</a>
<!-- <a href="javascript:;" onclick="render(data)">查看所有</a> -->
<!-- 上行代码 点击时调用render函数时不用传参 → render已设默认参数data -->
<a href="javascript:;" onclick="render()">查看所有</a>
</p>
<p class="line">
<span class="tip">判 断</span>
<a href="javascript:;" onclick="isAdvanced()">是否都是高级课程</a>
<a href="javascript:;" onclick="is5w()">是否有超过5万学习人数的课程</a>
</p>
</div>
<!-- 精品课程 -->
<div class="hd">
<h3>精品推荐</h3>
</div>
<div class="bd">
<ul class="common">
<!-- <li>
<a href="#">
<div class="pic"><img src="./uploads/quality01.png" alt=""></div>
<h4>JavaScript数据看板项目实战</h4>
<p><span>高级</span> · <i>1125</i>人在学习</p>
</a>
</li>-->
</ul>
</div>
</div>
<script>
let data = [
{
src: './uploads/quality01.png',
title: 'JavaScript数据看板项目实战',
num: 1125,
tag: 'javascript',
type: '高级',
time: 1650988800000
},
{
src: './uploads/quality02.png',
title: 'Vue.js实战——面经全端项目',
num: 2726,
tag: 'vue',
type: '高级',
time: 1668816000000
},
{
src: './uploads/quality03.png',
title: '玩转Vue全家桶,iHRM人力资源项目',
num: 9456,
tag: 'vue',
type: '高级',
time: 1687017600000
},
{
src: './uploads/quality04.png',
title: 'Vue.js实战医疗项目——优医问诊',
num: 7192,
tag: 'vue',
type: '高级',
time: 1678809600000
},
{
src: './uploads/quality05.png',
title: '小程序实战:小兔鲜电商小程序项目',
num: 2703,
tag: '小程序',
type: '高级',
time: 1691424000000
},
{
src: './uploads/quality06.png',
title: '前端框架Flutter开发实战',
num: 2841,
tag: 'flutter',
type: '高级',
time: 1648742400000
},
{
src: './uploads/quality07.png',
title: '熟练使用React.js——极客园H5项目',
num: 95682,
tag: 'react',
type: '高级',
time: 1651852800000
},
{
src: './uploads/quality08.png',
title: '熟练使用React.js——极客园PC端项目',
num: 904,
tag: 'react',
type: '高级',
time: 1646150400000
},
{
src: './uploads/quality09.png',
title: '前端实用技术,Fetch API 实战',
num: 1516,
tag: 'fetch',
type: '高级',
time: 1660060800000
},
{
src: './uploads/quality10.png',
title: '前端高级Node.js零基础入门教程',
num: 2766,
tag: 'nodejs',
type: '高级',
time: 1675008000000
}
]
// 查找所有Vue视频(filter)
function allVue() {
// console.log(111)
// 筛选出tag属性值为'vue'的元素,返回新数组
/* const arrAllVue = data.filter((el) => {
return el.tag === 'vue'
}) */
// 箭头函数简写 一个参数省略(),函数体一行代码省略return和{}
const arrAllVue = data.filter(el => el.tag === 'vue')
render(arrAllVue)
}
// 查找最先超过5K学习人数(find)
function find5K() {
// 方法1. find
/* const arrFind5K = []
arrFind5K[0] = data.find(el => el.num > 5000)
console.log(arrFind5K)
render(arrFind5K) */
// 方法2. findIndex
/* const index = data.findIndex(el => el.num > 5000)
const arrFind5K1 = []
arrFind5K1[0] = data[index]
render(arrFind5K1) */
// 课上方法
const obj = data.find(el => el.num > 5000)
render([obj])
}
// 是否都是高级内容
function isAdvanced() {
// const flag = data.every(el => el.type === '高级')
// alert(flag) // true
/* if (flag === true) {
alert('是')
} else {
alert('否')
} */
// flag === true ? alert('是') : alert('否')
// flag ? alert('是') : alert('否')
// alert(flag === true ? '是' : '否')
// alert(flag ? '是' : '否')
data.every(el => el.type === '高级') ? alert('是') : alert('否')
}
// 是否有超过5万学习人数的内容
function is5w() {
// const flag = data.some(el => el.num > 50000)
// alert(flag) // true
data.some(el => el.num > 50000) ? alert('是') : alert('否')
}
// 渲染函数
render()
// arr形参默认值为data。默认渲染data数组中全部元素
function render(arr = data) {
const str = arr.map(item => {
const { src, title, num, time } = item
// 格式化处理时间
const formatTime = new Date(time).toLocaleDateString()
return `
<li>
<a href="#">
<div class="pic">
<img src="${src}" alt="">
</div>
<h4>${title}</h4>
<p><span>高级</span> · <i>${num}</i>人在学习</p>
<span class="date">${formatTime}</span>
</a>
</li>
`
}).join('')
document.querySelector('.bd ul').innerHTML = str
}
</script>
</body>
</html>
2. 对象常用方法
2.1 Object.keys() 获取对象键
2.2 Object.values() 获取对象值
2.3 Object. assign() 对象深拷贝
<!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>
const pig = {
name: '佩奇',
age: 6
}
// 1. Object.keys() 获取对象中所有属性(键),返回为一个数组
const arr1 = Object.keys(pig)
console.log(arr1) // ['name', 'age']
// 2. Object.values() 获取对象中所有属性值,返回为一个数组
const arr2 = Object.values(pig)
console.log(arr2) // ['佩奇', 6]
// 3. Object.assign() 常用于对象拷贝(深拷贝)
const obj1 = {}
Object.assign(obj1, pig)
pig.name = 'peiqi'
console.log(pig) // {name: 'peiqi', age: 6}
console.log(obj1) // {name: '佩奇', age: 6}
const zhu = pig // 浅拷贝 修改一个另一个跟着变
</script>
</body>
</html>
2.4 案例2_拼接字符串
<!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 class="box1"></div>
<div class="box2"></div>
<script>
const spec = { size: '40cm*40cm', color: '黑色' }
// 方式一:对象.属性 +
const box1 = document.querySelector('.box1')
console.log(spec.size + '/' + spec.color) // 40cm*40cm/黑色
box1.innerHTML = spec.size + '/' + spec.color
// 方式二. values().join()
const box2 = document.querySelector('.box2')
console.log(Object.values(spec).join('/')) // 40cm*40cm/黑色
box2.innerHTML = Object.values(spec).join('/')
</script>
</body>
</html>
3. 字符串常用方法
3.1 length 字符串长度
3.2 split 将字符串拆分成数组
<!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>
<!--
length 用来获取字符串的长度(重点)
split('分隔符')用来将字符串拆分成数组(重点)
-->
<script>
const str = '黑马程序员'
console.log(str.length) // 5
console.log(str.split('')) // ['黑', '马', '程', '序', '员']
console.log(str.split('').reverse().join('')) // 员序程马黑
const str1 = '小米,华为,苹果'
console.log(str1.length) // 8
console.log(str1.split(',')) // ['小米', '华为', '苹果']
</script>
</body>
</html>
3.3 案例3_渲染赠品
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>赠品小案例</title>
<style>
.tag {
display: block;
}
</style>
</head>
<body>
<p class="name1">
<!-- <span class="tag"></span> -->
</p>
<p class="name2"></p>
<script>
const gift = '50g茶叶,清洗球'
// 分割为数组 → map:标签字符串 → 追加内容到 p 标签
const str = gift.split(',').map(el => `<span class="tag">[赠品]${el}</span>`).join('')
document.querySelector('.name1').innerHTML = str
// 分割为数组
const arr = gift.split(',')
// map+join
const str1 = arr.map(el => `<span class="tag">[赠品]${el}</span>`).join('')
document.querySelector('.name2').innerHTML = str1
</script>
</body>
</html>
3.4 substring、startsWith、endsWith、includes
<!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>
const str = '传智播客传递知识'
// 0. substring (需要截取的第一个字符的索引l[,结束的索引号]) 用于字符串截取(重点)
// 包含开始,不包含结束位置的字符串(左闭右开)
console.log(str.substring(0, 3)) // 传智播
// 不写结束位置索引,表示从开始到最后
console.log(str.substring(1)) // 智播客传递知识
// 不写开始位置索引
// console.log(str.substring( , 2)) // 编辑器报错
// 1. startsWith(检测字符,[检测位置]) (重点)
// 检测是否以某个/些字符开头,返回布尔值
console.log(str.startsWith('传智')) // true
console.log(str.startsWith('智')) // false
console.log(str.startsWith('智', 2)) // false
console.log(str.startsWith('智', 1)) // true
// 2. endsWith(检测字符,[字符串长度])
// 检测是否以某个/些字符结尾,返回布尔值
console.log(str.length) // 8
console.log(str.endsWith('知识')) // true
console.log(str.endsWith('知', 8)) // false
console.log(str.endsWith('识', 8)) // true
const str1 = "To be, or not to be, that is the question."
// 3. includes(搜索的字符,[检测位置])
// 判断一个字符串是否 包含 在另外一个字符串中,返回布尔值
console.log(str1.length) // 42
console.log(str1.includes('is', 25)) // true
console.log(str1.includes('is', 35)) // false
</script>
</body>
</html>
3.5 trim、toUpperCase、toLowerCase、indexOf
<!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>
// 1. 字符串trim方法: 可以去除字符串两侧的空格,返回一个新的字符串,而不修改原始字符串
const str = ' pi nk '
console.log(str.length) // 7
console.log(str.trim()) // pi nk
console.log(str.trim().length) // 5
// 这是用户输入的内容
const content = ' '
console.log(content.length) // 9
console.log(content.trim()) // (空)
console.log(content.trim().length) // 0
// 2. toUpperCase 用于将字母转换成大写
console.log(str.trim().toUpperCase()) // PI NK
const str1 = 'Hello'
console.log(str1.toUpperCase()) // HELLO
const str2 = 'HELLO'
// 3. toLowerCase 用于将字母转换成小写
console.log(str1.toLowerCase()) // hello
console.log(str2.toLowerCase()) // hello
// 4. indexOf 检测是否包含某字符,包含返回索引,不包含返回-1
console.log(str2.indexOf('H')) // 0
console.log(str2.indexOf('LL')) // 2
console.log(str2.indexOf('H1')) // -1
</script>
</body>
</html>
4. 日期
<!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>
// 获得当前日期
const date1 = new Date()
console.log(date1) // Wed Nov 20 2024 15:24:25 GMT+0800 (中国标准时间)
// 获得年份
console.log(date1.getFullYear()) // 2024
// 获得月份 值为0-11对应实际1-12
console.log(date1.getMonth()) // 10
// 获取月份中的每一天
console.log(date1.getDate()) // 20
// 获取星期 0-6 0为周日
console.log(date1.getDay()) // 3
// 获取小时
console.log(date1.getHours()) // 15
// 获取分钟
console.log(date1.getMinutes()) // 24
// 获取秒
console.log(date1.getSeconds()) // 25
// 获得指定日期
const date2 = new Date('2025-1-1')
console.log(date2) // Wed Jan 01 2025 00:00:00 GMT+0800 (中国标准时间)
</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>
const date = new Date()
console.log(date.toLocaleString()) // 2024/11/20 15:47:47
console.log(date.toLocaleDateString()) // 2024/11/20
console.log(date.toLocaleTimeString()) // 15:47:47
// UTC(协调世界时); GMT,即格林尼治标准时间,也是 UTC 的另一种说法
console.log(date.toUTCString()) // Wed, 20 Nov 2024 07:47:47 GMT
// toLocaleDateString
// 时间戳(毫秒数)
const time = 1651852800000
const formatTime = new Date(time).toLocaleDateString()
console.log(formatTime) // 2022/5/7
</script>
</body>
</html>
5. 递归函数
<!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>
// 递归函数:函数内部自己调用自己
// 由于递归很容易发生“栈溢出”错误(stack overflow),所以记得添加退出条件
/* function fn1() {
console.log(1)
fn1()
}
fn1() */
// 最终报错 Uncaught RangeError: Maximum call stack size exceeded 栈溢出
let num = 0
function fn2() {
console.log(num)
num++
if (num < 5) {
fn2()
}
}
fn2()
</script>
</body>
</html>
案例4_扁平化处理数据
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="index.css">
</head>
<body>
<section class="container">
<div class="department">
<h3>本公司所有员工</h3>
<ul>
<!-- <li>
<img class="avatar" src="./imgs/user3.jpg" alt="">
<span class="username">Jack</span>
<span class="born-time">2023-10-1</span>
<span class="sex">男</span>
</li> -->
</ul>
</div>
</section>
<script>
const treeData = [
{
id: 1,
departmentName: '人力资源部',
parentId: null,
children: [
{
id: 12,
username: '张三',
avatar: './imgs/user1.jpg',
sex: '男',
birth: 1693039237877,
parentId: 1,
children: [
{
id: 113,
username: '李华',
avatar: './imgs/user3.jpg',
sex: '男',
birth: 1693039237877,
parentId: 1,
children: [],
}
],
},
{
id: 13,
username: '张浩',
avatar: './imgs/user3.jpg',
sex: '男',
birth: 1693039237877,
parentId: 1,
children: [],
},
],
},
{
id: 2,
departmentName: '技术部',
parentId: null,
children: [
{
id: 24,
username: '李四',
avatar: './imgs/user2.jpg',
sex: '男',
birth: 1693039237877,
parentId: 2,
children: [],
},
],
},
]
/* if (children.length !== 0) {
fn()
} */
// 树形列表 转 列表,过滤出 员工(有parentId)渲染 为 li 标签
function fn(array) {
let arr = []
array.forEach(element => {
// 解构对象
const { children, ...other } = element
arr.push(other)
if (children.length !== 0) {
arr.push(...fn(children))
// fn(children)
}
})
console.log(arr)
return arr
}
const res = fn(treeData)
// console.log(res)
// 筛选res 将员工追加到新数组res1
const res1 = res.filter(element => {
// return Boolean(element.parentId) === true
// 隐式转换
return element.parentId
})
// console.log(res1)
// map+join 迭代res1数组并拼接字符串
const str = res1.map(element => {
const { avatar, username, birth, sex } = element
const time = new Date(birth).toLocaleDateString()
return `
<li>
<img class="avatar" src="${avatar}" alt="">
<span class="username">${username}</span>
<span class="born-time">${time}</span>
<span class="sex">${sex}</span>
</li>
`
}).join('')
// console.log(str)
document.querySelector('ul').innerHTML = str
</script>
</body>
</html>
6. 作业
6.1 数组常用方法
<!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>
// 第一题:能够实现map 映射得到新数组
fn1()
function fn1() {
// 原数组
const input = [
'生煎',
'灌汤包',
'水饺',
'汉堡',
]
// 请把input数组转换为以下格式:
const output = [
{
label: '生煎',
value: '生煎',
},
{
label: '灌汤包',
value: '灌汤包',
},
{
label: '水饺',
value: '水饺',
},
{
label: '汉堡',
value: '汉堡',
},
]
// 填入代码
const newArr = input.map(el => {
return ({
label: el,
value: el,
})
})
console.log(newArr)
}
// 第二题:
fn2()
function fn2() {
// 已知有以下数据:
const data = [
{
sku: '1001',
name: 'iPhone 7 Plus 128G 玫瑰金色 移动联通电信4G手机',
is5G: false,
price: 6188,
count: 100, // 库存
suggestions: [
'1002',
'1003',
'1004',
], // 相关推荐
},
{
sku: '1002',
name: 'iPhone 14 Pro 256G 深空灰色 移动联通电信5G手机',
is5G: true,
price: 9999,
count: 100,
suggestions: [
'1001',
'1003',
],
},
{
sku: '1003',
name: 'iPhone 14 Pro Max 256G 深空灰色 移动联通电信5G手机',
is5G: true,
price: 10999,
count: 0,
suggestions: [
'1001',
'1002',
],
},
{
sku: '1004',
name: 'iPhone 14 Pro Max 256G 白色 移动联通电信5G手机',
is5G: true,
price: 10999,
count: 9,
suggestions: [
'1001',
],
},
]
// 请完成以下需求:
// 1. 找出所有5G手机
const newData1 = data.filter(el => {
return el.is5G === true
})
console.log(newData1)
// 2. 找出所有有货的手机
const newData2 = data.filter(el => {
return el.count > 0
})
console.log(newData2)
// 3. 找出所有有货的5G手机
const newData3 = data.filter(el => {
return el.is5G === true && el.count > 0
})
console.log(newData3) //
// 4. 找出所有有货的5G手机的总价格(数量 * 单价)
const num = newData3.reduce((prev, current) => {
return prev + current.price * current.count
}, 0)
console.log(num) // 1098891
}
// 第三题:
fn3()
function fn3() {
// 有如下数据
const data = [
{
id: '1faa0e81', // 快递单号
from: { // 发件人信息
name: '张三',
id: '1412908431238',
phone: '13800138000',
address: '北京市朝阳区望京soho',
},
to: { // 收件人信息
name: '李四',
id: '1412908431239',
phone: '13800138001',
address: '北京市海淀区西二旗',
},
timestamp: 1610000000000, // 时间戳
status: 'pending', // 状态 pending在途中 resolved已签收 rejected拒签
goodsType: 'food', // 类型 food食品 electronic电子
price: 18, // 价格
type: '次日达', // 快递类型
},
{
id: '1faa0e82',
from: {
name: '张武',
id: '1412908431240',
phone: '13800138002',
address: '重庆市渝中区渝中路',
},
to: {
name: '李六',
id: '1412908431241',
phone: '13800138003',
address: '重庆市渝北区渝北路',
},
timestamp: 1610000123123,
status: 'resolved',
goodsType: 'electronics',
price: 188,
type: '次日达',
},
{
id: '1faa0e83',
from: {
name: '赵信',
id: '1412908431242',
phone: '13800138004',
address: '上海市浦东新区张江高科',
},
to: {
name: '王9',
id: '1412908431243',
phone: '13800138005',
address: '深圳市南山区科技园',
},
timestamp: 1610000123124,
status: 'pending',
goodsType: 'food',
price: 18,
type: '次日达',
},
{
id: '1faa0e84',
from: {
name: '蛮王',
id: '1412908431244',
phone: '13800138006',
address: '重庆市渝中区千与千寻小区',
},
to: {
name: '艾希',
id: '1412908431245',
phone: '13800138007',
address: '重庆市渝北区中央公园',
},
timestamp: 1610000123125,
status: 'rejected',
goodsType: 'flowers',
price: 99,
type: '隔日达',
},
]
// 请完成以下需求
// 1. 找出所有food类型的订单
const data3new1 = data.filter(el => {
return el.goodsType === 'food'
})
console.log(data3new1)
// 2. 找出所有次日达的订单
const data3new2 = data.filter(el => {
return el.type === '次日达'
})
console.log(data3new2)
// 3. 找出所有次日达的food类型的订单
const data3new3 = data.filter(el => {
return el.goodsType === 'food' && el.type === '次日达'
})
console.log(data3new3)
// 4. 统计快递的拒签率(rejected为退回)
// for遍历
let num = 0
for (let i = 0; i < data.length; i++) {
data[i].status === 'rejected' ? num++ : num
}
console.log(`快递的拒签率为${(num / data.length) * 100}%`)
// forEach遍历
let num1 = 0
data.forEach(element => {
element.status === 'rejected' ? num1++ : num1
})
console.log(`快递的拒签率为${(num1 / data.length) * 100}%`)
// 5. 找出所有在途中的订单(即pending状态的订单)
const data3new5 = data.filter(el => {
return el.status === 'pending'
})
console.log(data3new5)
}
// --------------------------------------------------------------
// 封装函数,求得数组中的最大值
function getMax(arrry) {
// 填入代码
let max = arrry[0]
for (let i = 1; i < arrry.length; i++) {
max = max > arrry[i] ? max : arrry[i]
}
return max
}
let arr = [1, 6, 2, 8, 11, 5]
let max = getMax(arr)
console.log(max) // 11
// --------------------------------------------------------------
// 封装函数,求得传入数组元素的和
function getSum(arr) {
// 填入代码
let sum = 0
arr.forEach(element => {
sum += element
})
return sum
}
let arr2 = [3, 9, 9, 2, 7, 5]
let sum2 = getSum(arr2)
console.log(sum2) // 35
// --------------------------------------------------------------
// 封装函数,求得传入数组⾥⼤于 5 的和
function getLargeSum(arr) {
// 填入代码
let sum = arr.filter(el => el > 5).reduce((prev, current) => {
return prev + current
}, 0)
return sum
}
let arr3 = [4, 9, 6, 90, 3, 11]
let sum3 = getLargeSum(arr3)
console.log(sum3) // 116
// --------------------------------------------------------------
// 封装函数,对数组,按照价格进行升序排序
function sortByAsc(arr) {
// 填入代码
return arr.sort((a, b) => a.price - b.price)
}
const arr4 = [
{ id: 1, name: '茶杯', price: 18 },
{ id: 2, name: '电视机', price: 2000 },
{ id: 3, name: '牙刷', price: 8 },
{ id: 4, name: '电脑', price: 5000 },
]
const res4 = sortByAsc(arr4)
console.log(res4)
// ---------------------------------------------------------------
// 封装函数,将学生数组中的所有姓名,存入成一个新数组,
// 并过滤掉小强 => 得到 ['小明', '小丽', '小美']
function getNames(arr) {
// 填入代码
const newArr = arr.map(el => {
return el.name
}).filter(el => {
return el !== '小强'
})
return newArr
}
const arr5 = [
{ id: 1, name: '小强', score: 18 },
{ id: 2, name: '小明', score: 2000 },
{ id: 3, name: '小丽', score: 8 },
{ id: 4, name: '小美', score: 5000 },
]
const res5 = getNames(arr5)
console.log(res5) // ['小明', '小丽', '小美']
</script>
</body>
</html>
6.2 收藏夹
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="./fonts/iconfont.css">
<link rel="stylesheet" href="./css/index.css">
</head>
<body>
<div class="container">
<h1>收藏夹</h1>
<div class="list">
<div class="title">
<h2>收藏夹栏</h2>
<div class="tools">
<!-- 显示全部 -->
<span onclick="render()"><i class="iconfont icon-eye"></i>显示全部</span>
<!-- 搜索-放大镜 -->
<span onclick="search()"><i class="iconfont icon-fangdajing"></i>搜索</span>
<!-- 添加文件夹 -->
<span onclick="add()"><i class="iconfont icon-24gf-folderPlus"></i>添加</span>
</div>
</div>
<ul id="listUl">
<li>
<p><i class="iconfont icon-24gf-folderOpen"></i> Lesson</p>
<!-- 删除 -->
<i class="iconfont icon-guanbi" onclick="del(0)"></i>
</li>
</ul>
</div>
</div>
<script>
// 默认渲染的收藏夹
let arr = [
'Vue2',
'Vue3',
'React',
'Uni-app',
'JS',
'TS',
]
render()
// 功能1:渲染函数
function render(array = arr) {
const str = array.map((el, index) => {
return `
<li>
<p><i class="iconfont icon-24gf-folderOpen"></i>${el}</p>
<i class="iconfont icon-guanbi" onclick="del(${index})"></i>
</li>
`
}).join('')
document.querySelector('#listUl').innerHTML = str
}
// 功能2:删除功能
function del(index) {
arr.splice(index, 1)
render(arr)
}
// 功能3:添加功能
function add() {
let str = prompt('输入添加的收藏夹名称')
/* if (str.trim().length <= 0) {
alert('请正确输入')
return
} */
if (!str.trim()) {
alert('请正确输入')
return
}
arr.unshift(str)
render()
}
// 功能4:搜索功能
function search() {
const lesson = prompt('请输入搜索的收藏夹名称')
const newArr = arr.filter(el => {
// return el.includes(`${lesson}`)
// 模糊搜索,不区分大小写
return el.toLowerCase().includes(`${lesson.trim().toLowerCase()}`)
})
render(newArr)
}
</script>
</body>
</html>
6.3 判断是否为数组
<!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.isArray() 方法来判断以下数据是否为数组
const arr = []
const likeArray = { 0: 'apple', 1: 'banner', length: 2 }
console.log(Array.isArray(arr)) // true
console.log(Array.isArray(likeArray)) // false
</script>
</body>
</html>
6.4 flat
<!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>
// 通过flat方法实现 [[1, 2], [3, [4, 5]], 6],处理得到新数组 [1, 2, 3, 4, 5, 6]
const arr = [[1, 2], [3, [4, 5]], 6]
const newArr = arr.flat().flat()
console.log(newArr) // [1, 2, 3, 4, 5, 6]
const newArr1 = arr.flat(1)
console.log(newArr1) // [1, 2, 3, [4, 5], 6]
const newArr2 = arr.flat(2)
console.log(newArr2) // [1, 2, 3, 4, 5, 6]
</script>
</body>
</html>
6.5 对象深拷贝
<!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>
// 递归实现深拷贝 - 简版实现对象和数组的拷贝
const obj = {
name: '佩奇',
family: {
father: '猪爸爸',
},
hobby: ['跳泥坑', '唱歌'],
}
console.log(obj)
/* const pig = {}
Object.assign(pig, obj)
console.log(pig) */
// 封装深拷贝函数 cloneDeep()
function cloneDeep(oldObj) {
// 先判断拷贝的是数组还是对象
const newObj = Array.isArray(oldObj) ? [] : {}
// 遍历拷贝属性和值
for (let k in oldObj) {
// console.log(k) // k 是属性
// console.log(oldObj[k]) // oldObj[k] 是属性值
// 把旧对象的值给新对象的属性
if (typeof oldObj[k] === 'object') {
// 如果属性值是引用数据类型,则需要递归再次拷贝
newObj[k] = cloneDeep(oldObj[k])
} else {
// 否则属性值是基本数据类型,则直接赋值即可
newObj[k] = oldObj[k]
}
}
// 返回新对象
return newObj
}
const newObj = cloneDeep(obj)
newObj.family.father = 'dad'
console.log(newObj)
console.log(obj)
</script>
</body>
</html>
241121
7. 案例5_购物车
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<link rel="stylesheet" href="./css/car.css">
</head>
<body>
<div class="list">
<div class="item">
<img src="https://yanxuan-item.nosdn.127.net/84a59ff9c58a77032564e61f716846d6.jpg" alt="">
<p class="name">称心如意手摇咖啡磨豆机咖啡豆研磨机 <span class="tag">【赠品】10优惠券</span> <span class="time">2022/8/20</span>
</p>
<p class="spec">白色/10寸</p>
<p class="price">289.90</p>
<p class="count">x2</p>
<p class="sub-total">579.80</p>
</div>
</div>
<div class="total">
<div>
合计:
<span class="amount">1000.00</span>
</div>
</div>
<script>
const goodsList = [
{
id: '4001172',
name: '称心如意手摇咖啡磨豆机咖啡豆研磨机',
price: 289.9,
picture:
'https://yanxuan-item.nosdn.127.net/84a59ff9c58a77032564e61f716846d6.jpg',
count: 2,
spec: { color: '白色' },
},
{
id: '4001009',
name: '竹制干泡茶盘正方形沥水茶台品茶盘',
price: 109.8,
picture:
'https://yanxuan-item.nosdn.127.net/2d942d6bc94f1e230763e1a5a3b379e1.png',
count: 3,
spec: { size: '40cm*40cm', color: '黑色' },
},
{
id: '4001874',
name: '古法温酒汝瓷酒具套装白酒杯莲花温酒器',
price: 488,
picture:
'https://yanxuan-item.nosdn.127.net/44e51622800e4fceb6bee8e616da85fd.png',
count: 1,
spec: { color: '青色', sum: '一大四小' },
gift: '500g茶叶,羽毛球',
},
{
id: '4001649',
name: '大师监制龙泉青瓷茶叶罐',
price: 139,
picture:
'https://yanxuan-item.nosdn.127.net/4356c9fc150753775fe56b465314f1eb.png',
count: 2,
spec: { size: '小号', color: '紫色' },
gift: '50g茶叶,清洗球',
},
]
render(goodsList)
function render(data) {
const str = data.map(el => {
const { name, price, picture, count, spec, gift } = el
// const { size, color } = spec
const specStr = Object.values(spec).join('/')
// console.log(gift?.split(','))
const giftStr = gift
? gift.split(',').map(el => `<span class="tag">【赠品】${el}</span>`).join('')
: ''
return `
<div class="item">
<img src="${picture}" alt="">
<p class="name">${name} ${giftStr} <span class="time">2022/8/20</span>
</p>
<p class="spec">${specStr}</p>
<p class="price">${price.toFixed(2)}</p>
<p class="count">x${count}</p>
<p class="sub-total">${(price * count).toFixed(2)}</p>
</div>
`
}).join('')
document.querySelector('.list').innerHTML = str
const allPrice = data.reduce((prev, current) => {
return prev + current.count * current.price
}, 0)
document.querySelector('.amount').innerHTML = allPrice.toFixed(2)
}
</script>
</body>
</html>
8. 异常处理
8.1 throw 抛异常
<!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>
<!-- 异常处理是指预估代码执行过程中可能发生的错误,
然后最大程度的避免错误的发生导致整个程序无法继续运行.
了解 JavaScript 中程序异常处理的方法,提升代码运行的健壮性。
-->
<!--
throw 抛异常
1. throw 抛出异常信息,程序也会终止执行
2. throw 后面跟的是错误提示信息
3. Error 对象配合 throw 使用,能够设置更详细的错误信息
-->
<script>
function fn(x, y) {
if (!x || !y) {
throw new Error('传入两个参数都不能为空')
}
console.log(x + y)
}
fn(1, 2)
fn(1)
</script>
</body>
</html>
8.2 try /catch 捕获异常
<!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>
<p>这是文字p</p>
<!--
try /catch 捕获异常
try试试 catch拦住 finally最后
1. 将预估可能发生错误的代码写在 try 代码段中
2. 如果 try 代码段中出现错误后,会执行 catch 代码段,并截获到错误信息
3. finally 不管是否有错误,都会执行
-->
<script>
// 正确写法
/* const p = document.querySelector('p')
p.innerHTML = 'js' */
/* const p = document.querySelector('.p')
p.innerHTML = 'js' */
try {
const p = document.querySelector('p')
// 可能出错的代码
// const p = document.querySelector('.p')
p.innerHTML = 'js'
} catch (error) {
console.log(error)
} finally {
console.log('finally不管是否有错误,都会执行')
}
console.log('1')
</script>
</body>
</html>