From f41e2f6241ef3cf98f90911768f700c8009349e2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E8=B0=A2=E9=93=96=E6=B5=A9?= <1136734375@qq.com>
Date: Thu, 28 Dec 2023 21:50:26 +0800
Subject: [PATCH] =?UTF-8?q?=E7=AC=94=E8=AE=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../10.26\344\275\234\344\270\232.md" | 27 +
...27\346\227\245\344\275\234\344\270\232.md" | 96 ++++
...31\346\227\245\344\275\234\344\270\232.md" | 189 +++++++
.../11.28.md" | 179 ++++++
.../11.30.md" | 140 +++++
.../11.9.md" | 60 ++
...10\346\227\245\344\275\234\344\270\232.md" | 221 ++++++++
...01\346\227\245\344\275\234\344\270\232.md" | 39 ++
...21\346\227\245\344\275\234\344\270\232.md" | 82 +++
.../11\346\234\21030\346\227\245.md" | 166 ++++++
...07\346\227\245\344\275\234\344\270\232.md" | 166 ++++++
...08\346\227\245\344\275\234\344\270\232.md" | 31 ++
.../12.1.md" | 498 +++++++++++++++++
.../12.11.md" | 156 ++++++
.../12.12.md" | 30 +
.../12.13.md" | 165 ++++++
.../12.14.md" | 243 ++++++++
.../12.6.md" | 77 +++
.../12.7.md" | 88 +++
.../12\346\234\2107\346\227\245.md" | 38 ++
.../20231202 \350\277\233\351\230\266 .md" | 523 ++++++++++++++++++
...6\344\271\246\347\256\241\347\220\206 .md" | 140 +++++
22 files changed, 3354 insertions(+)
create mode 100644 "05 \350\260\242\351\223\226\346\265\251/10.26\344\275\234\344\270\232.md"
create mode 100644 "05 \350\260\242\351\223\226\346\265\251/10\346\234\21027\346\227\245\344\275\234\344\270\232.md"
create mode 100644 "05 \350\260\242\351\223\226\346\265\251/10\346\234\21031\346\227\245\344\275\234\344\270\232.md"
create mode 100644 "05 \350\260\242\351\223\226\346\265\251/11.28.md"
create mode 100644 "05 \350\260\242\351\223\226\346\265\251/11.30.md"
create mode 100644 "05 \350\260\242\351\223\226\346\265\251/11.9.md"
create mode 100644 "05 \350\260\242\351\223\226\346\265\251/11\346\234\21010\346\227\245\344\275\234\344\270\232.md"
create mode 100644 "05 \350\260\242\351\223\226\346\265\251/11\346\234\2101\346\227\245\344\275\234\344\270\232.md"
create mode 100644 "05 \350\260\242\351\223\226\346\265\251/11\346\234\21021\346\227\245\344\275\234\344\270\232.md"
create mode 100644 "05 \350\260\242\351\223\226\346\265\251/11\346\234\21030\346\227\245.md"
create mode 100644 "05 \350\260\242\351\223\226\346\265\251/11\346\234\2107\346\227\245\344\275\234\344\270\232.md"
create mode 100644 "05 \350\260\242\351\223\226\346\265\251/11\346\234\2108\346\227\245\344\275\234\344\270\232.md"
create mode 100644 "05 \350\260\242\351\223\226\346\265\251/12.1.md"
create mode 100644 "05 \350\260\242\351\223\226\346\265\251/12.11.md"
create mode 100644 "05 \350\260\242\351\223\226\346\265\251/12.12.md"
create mode 100644 "05 \350\260\242\351\223\226\346\265\251/12.13.md"
create mode 100644 "05 \350\260\242\351\223\226\346\265\251/12.14.md"
create mode 100644 "05 \350\260\242\351\223\226\346\265\251/12.6.md"
create mode 100644 "05 \350\260\242\351\223\226\346\265\251/12.7.md"
create mode 100644 "05 \350\260\242\351\223\226\346\265\251/12\346\234\2107\346\227\245.md"
create mode 100644 "05 \350\260\242\351\223\226\346\265\251/20231202 \350\277\233\351\230\266 .md"
create mode 100644 "05 \350\260\242\351\223\226\346\265\251/20231211 \345\233\276\344\271\246\347\256\241\347\220\206 .md"
diff --git "a/05 \350\260\242\351\223\226\346\265\251/10.26\344\275\234\344\270\232.md" "b/05 \350\260\242\351\223\226\346\265\251/10.26\344\275\234\344\270\232.md"
new file mode 100644
index 0000000..5866ccb
--- /dev/null
+++ "b/05 \350\260\242\351\223\226\346\265\251/10.26\344\275\234\344\270\232.md"
@@ -0,0 +1,27 @@
+一. 完成课堂所有的代码
+
+# JS
+
+## 内部代码
+
+
+
+外部代码
+
+
+
+const oneeEl = document.querySelector(".ac") / oneeEl.onclick = function() { alert("牛逼完了") }
+
+## 二. 简单聊聊JavaScript的历史(自己的话术来总结)
+
+JavaScript一种直译式脚本语言,它最初由Netscape的Brendan Eich设计。Netscape在最初将其脚本语言命名为LiveScript,后来Netscape在与Sun合作之后将其改名为JavaScript。JavaScript最初受Java启发而开始设计的,目的之一就是“看上去像Java”,因此语法上有类似之处,一些名称和命名规范也借自Java。
+
+## 三. 说说你对JS引擎的理解(自己的话术总结)
+
+**JavaScript引擎是一个专门处理JavaScript脚本的虚拟机,一般会附带在网页浏览器之中。
+
+## 四. JavaScript的交互方式有哪些?(后两种方式)
+
+1.警告(alert)
+
+2.确认(confirm)
\ No newline at end of file
diff --git "a/05 \350\260\242\351\223\226\346\265\251/10\346\234\21027\346\227\245\344\275\234\344\270\232.md" "b/05 \350\260\242\351\223\226\346\265\251/10\346\234\21027\346\227\245\344\275\234\344\270\232.md"
new file mode 100644
index 0000000..02fc97b
--- /dev/null
+++ "b/05 \350\260\242\351\223\226\346\265\251/10\346\234\21027\346\227\245\344\275\234\344\270\232.md"
@@ -0,0 +1,96 @@
+定义变量:const ,let ,var ,直接赋值
+
+Number数值,JavaScript 数值类型不再细分整型、浮点型等,js 的所有数值都属于浮点型,64位浮点数。
+
+String字符串,最抽象的数据类型,信息传播的载体,字符串必须包含在单引号、双引号或反引号之中,一个字符两个字节。
+
+Boolean布尔值,最机械的数据类型,逻辑运算的载体,仅有两个值,true / false。Symbol符号类型,ES6 引入的一种新的原始数据类型,表示独一无二的值,不常用。
+
+undefined未定义,当声明变量而没有赋值时会显示该值,可以为变量赋值为 undefined。
+
+Object对象,是一种无序的数据集合,内容是键值对的形式,键名(key)是字符串,可以包含任意字符(空格),字符串引号可省略。可以通过 Object.keys(obj) 打印出 obj 对象中的所有 key 值。读对象的属性时,如果使用 [ ] 语法,那么 JS 会先求 [ ] 中表达式的值。如果使用点语法,那么点后面一定是 string 常量。
+
+```
+\' 单引号
+\" 双引号
+\\ 反斜杠
+\n 换行符
+\r 回车符
+\t 制表符
+\b 退格符
+转义字符串开发中只有特殊场景才会用到,暂时掌握 \’\” \t \n四个的用法即可。
+```
+
+= 赋值 a=10,将10赋值给变量a
+
++= 加后赋值 a+=b,将a+b的值给a a = a+b;
+
+-= 减后赋值 a-=b,将a-b的值给a a=a-b;
+
+*= 乘后赋值 a*=b*,将*a×b*的值给*a a=a*b;
+
+/= 除后赋值 a/=b,将a÷b的商给a a=a/b;
+
+%= 取余后赋值 a%=b,将a÷b的余数给a a=a%b;
+
+&
+
+逻辑与 and
+
+a&b,a和b都是true,结果为true,否则为false
+
+|
+
+逻辑或 or
+
+a|b,a和b都是false,结果为false,否则为true
+
+^
+
+逻辑异或 不能有相等的关系
+
+a^b,a和b结果不同为true,相同为false
+
+!
+
+逻辑非 not
+
+!a,结果和a的结果正好相反
+
+三元运算符语法格式:关系表达式?表达式1:表达式2;
+
+```
+顺序结构
+分支结构(if, switch)
+循环结构(for, while, do…while)
+
+格式:
+if(关系表达式){
+ 语句体;
+}
+
+switch (表达式) {
+case 1:
+语句体1;
+break;
+case 2:
+语句体2;
+break;
+...
+default:
+语句体n+1;
+break;
+}
+
+for (初始化语句;条件判断语句;条件控制语句) {
+循环体语句;
+}
+
+while (条件判断语句) {
+循环体语句;
+条件控制语句;
+}
+执行条件判断语句,看其结果是true还是false
+ 如果是false,循环结束
+ 如果是true,继续执行
+```
\ No newline at end of file
diff --git "a/05 \350\260\242\351\223\226\346\265\251/10\346\234\21031\346\227\245\344\275\234\344\270\232.md" "b/05 \350\260\242\351\223\226\346\265\251/10\346\234\21031\346\227\245\344\275\234\344\270\232.md"
new file mode 100644
index 0000000..3b776d0
--- /dev/null
+++ "b/05 \350\260\242\351\223\226\346\265\251/10\346\234\21031\346\227\245\344\275\234\344\270\232.md"
@@ -0,0 +1,189 @@
+```
+
+
+
+
+
+
+ Document
+
+
+
+
+
+
+```
\ No newline at end of file
diff --git "a/05 \350\260\242\351\223\226\346\265\251/11.28.md" "b/05 \350\260\242\351\223\226\346\265\251/11.28.md"
new file mode 100644
index 0000000..671f93b
--- /dev/null
+++ "b/05 \350\260\242\351\223\226\346\265\251/11.28.md"
@@ -0,0 +1,179 @@
+```
+概念
+正则表达式是用于匹配字符串中字符组合的模式。在 JavaScript中,正则表达式也是对象。这些模式被用于 RegExp 的 exec 和 test 方法, 以及 String 的 match、matchAll、replace、search 和 split 方法。
+
+创建正则表达式
+两种方法:字面量方式、构造函数方式
+
+//字面量方式,其由包含在斜杠之间的模式组成,如下所示:
+var re = /ab+c/;
+//构造函数方式,调用RegExp对象的构造函数,如下所示:
+var re = new RegExp("ab+c");
+
+正则表达式常用方法
+校验数据
+test(字符串)
+测试字符是否满足正则表达式规则,如果测试到有,则返回true;没有则返回flase
+语法:正则表达式.test(字符串) 正则表达式提供的方法
+
+var reg=/[123]/
+var str='1'
+var result=reg.test(str)
+console.log(result)//flase
+
+search(正则表达式)
+search() 方法执行正则表达式和 String 对象之间的一个搜索匹配。
+语法:字符串.search(正则表达式) 字符串提供的方法
+
+var reg=/\d/ //匹配阿拉伯数字
+var str="abcdefg3sgbh"
+var res=str.search(reg)
+console.log(res) //7
+//验证方法 找到返回下标 找不到返回-1
+//在字符串中找到满足正则表达式的那一部分
+
+区别:
+.test()方法是正则表达式提供的,.search()是字符串提高的,
+.test()方法返回布尔值,search()返回下标
+
+提取数据
+正则表达式.exec(字符串)
+exec() 方法在一个指定字符串中执行一个搜索匹配。返回一个结果数组或 null。 正则表达式提供的方法
+
+var reg=/\d/
+var str="abcd456efg"
+var res=reg.exec(str)
+console.log(res)//返回一个数组,内容是4
+//字符串中满足正则表达式的部分提取出来
+//遇到满足条件的就返回,所以只返回4
+
+字符串.match(正则表达式)
+match() 方法检索返回一个字符串匹配正则表达式的结果。 字符串提供的方法
+
+var reg=/\d/
+var str="abcd456efg"
+var res=str.match(reg) //字符串中满足表达式的部分提取出来
+console.log(res)
+
+区别:
+正则表达式.exec(字符串),正则表达式提供的方法
+字符串.match(正则表达式) 字符串的方法
+相同:
+都返回一个数组,只要匹配到符合规则的数据就返回
+替换数据
+字符串.replace(正则表达式,新的内容)
+replace() 方法返回一个由替换值(replacement)替换部分或所有的模式(pattern)匹配项后的新字符串。模式可以是一个字符串或者一个正则表达式,替换值可以是一个字符串或者一个每次匹配都要调用的回调函数。如果pattern是字符串,则仅替换第一个匹配项。字符串提供的方法
+
+var reg=/\d/
+var str="11123bcd"
+var res=str.replace(reg,"a") //将数字换为a
+console.log(res)//a1123bcd 只要匹配到符合规则的就返回
+
+
+
+范围类
+在[]组成的类内部是可以连写的
+
+let text = 'a1B2d3X4Z5'
+let reg=/[a-zA-Z]/
+text.replace(reg,'Q')//Q1Q3Q4Q5
+
+字符类
+
+
+字符类取反
+很多时候碰到这么一种情况,即不想匹配某些字符,其他都匹配。此时,可以使用字符类取反——使用元字符^,创建反向类,即不属于某类的内容。
+
+[^abc]表示不是字符a或b或c的内容
+
+let reg=/[^abc]/g
+let text='a1b2c3d4e5'
+console.log(text.replace(reg,'X')) //输出aXbXcXdXeX
+
+修饰符
+在正常情况下,正则匹配到第一个匹配项则停止,并且默认大小写敏感,如果想修改默认选项,则需要修饰符。
+
+g:global全文搜索
+var reg=new RegExp('l');
+var a='hello'.replace(reg,'f')
+console.log(a)//输出结果为:heflo
+
+var reg=new RegExp('l','g');//加上g标签表示全文搜索
+var a='hello'.replace(reg,'f')
+console.log(a)//输出结果为:heffo (所有的 l 都换成了 f )
+
+i:ignore case 忽略大小写
+var reg=new RegExp('l','g');
+var a='helloHELLO'.replace(reg,'f')
+console.log(a)//输出结果为:heffoHELLO
+
+var reg=new RegExp('l','gi');//加上i标签表示忽略大小写
+var a='helloHELLO'.replace(reg,'f')
+console.log(a)//输出结果为:heffoHEffO (大写和小写的l都被替换了)
+
+m:multiple lines 多行搜索
+var reg=new RegExp('od')
+var str='so good\n so good'
+var result=str.replace(reg,'hi')
+console.log(result)
+//结果为:
+ so gohi
+ so good
+ //只给第一行匹配了
+
+var reg=new RegExp('od','gm')//加上m标签表示多行匹配
+var str='so good\n so good'
+var result=str.replace(reg,'hi')
+console.log(result)
+//结果为:
+ so gohi
+ so gohi
+
+其他标志符
+s:允许 . 匹配换行符。
+u:使用unicode码的模式进行匹配。
+y:执行“粘性(sticky)”搜索,匹配从目标字符串的当前位置开始。
+
+量词符
+
+
+贪婪模式
+之前说了正则表达式的量词,但量词会带来一个到底匹配哪个的问题
+例如:
+
+var str="12345678"
+var reg=/\d{3,6}/g
+str.replace(reg,'X') //X78
+
+可以看到结果是将123456 六个数字替换成了X,所以我们可以得到,正常模式下,正则表达式会尽可能多的匹配。正常情况下,正则表达式采用贪婪模式,即,尽可能多的匹配。
+
+非贪婪模式
+一但成功匹配不再继续尝试,这就是非贪婪模式。
+只需要在量词后加上?即可
+
+var str="12345678"
+var reg=/\d{3,6}?/g
+str.replace(reg,'X') //X45678
+
+分组
+在使用正则表达式的时候会想要匹配一串字符串连续出现多次的情况,使用()可以达到分组的功能
+例如:(hello){3}
+使用符号 | (或)实现选择的功能
+例如:
+
+var str='12341235'
+let reg=/123(4|5)/g
+//1234 1235二选一
+
+反向引用
+将一种格式的时间字符串:yyyy-MM-DD转为MM/DD/yyyy类型格式字符串。
+由于年月日是不固定的,没法直接转换为固定数值。这时我们可以使用反向引用解决这个问题。
+利用$n,n代表着分组的序号,序号是从1开始的。
+
+例如:
+
+let text='2022-02-23'
+let reg=/(\d{4})-(\d{2})-(\d{2})/
+let res=text.replace(reg,'$3/$2/$1')//将yyyy-MM-DD转换为MM/DD/yyyy
+console.log(res)
+```
\ No newline at end of file
diff --git "a/05 \350\260\242\351\223\226\346\265\251/11.30.md" "b/05 \350\260\242\351\223\226\346\265\251/11.30.md"
new file mode 100644
index 0000000..c95bdef
--- /dev/null
+++ "b/05 \350\260\242\351\223\226\346\265\251/11.30.md"
@@ -0,0 +1,140 @@
+`js
+
+
+
+```
+## 注册
+
+```js
+
+```
+
+## 首页
+
+```
+
+```
\ No newline at end of file
diff --git "a/05 \350\260\242\351\223\226\346\265\251/11.9.md" "b/05 \350\260\242\351\223\226\346\265\251/11.9.md"
new file mode 100644
index 0000000..81d781d
--- /dev/null
+++ "b/05 \350\260\242\351\223\226\346\265\251/11.9.md"
@@ -0,0 +1,60 @@
+```
+// 获取元素
+ let img=document.querySelector('.slider-wrapper img');
+ let p=document.querySelector('.slider-footer p');
+ let colo=document.querySelector('.slider-footer');
+ let shan=document.querySelector('.toggle .prev');
+ let xia=document.querySelector('.toggle .next');
+//通用函数
+ function nb(){
+ img.src=data[i].url;
+ p.innerHTML=data[i].title;
+ colo.style.backgroundColor=data[i].color;
+ document.querySelector(`.slider-indicator .active`).classList.remove('active');
+ document.querySelector(`.slider-indicator li:nth-child(${i+1})`).classList.add('active');
+ }
+//自动轮播
+ let i=0;
+ let set=setInterval(function (){
+ i++;
+ if (i>=data.length) {
+ i=0;
+ }
+ nb()
+ },1000);
+//鼠标移入
+colo.addEventListener('mouseenter',function(){
+ clearInterval(set);
+ });
+//鼠标离开
+colo.addEventListener('mouseleave',function(){
+ set=setInterval(function(){
+ i++;
+ if (i>=data.length) {
+ i=0;
+ }
+ img.src=data[i].url;
+ p.innerHTML=data[i].title;
+ colo.style.backgroundColor=data[i].color;
+ document.querySelector(`.slider-indicator .active`).classList.remove('active');
+ document.querySelector(`.slider-indicator li:nth-child(${i+1})`).classList.add('active');
+ },1000);
+ });
+//点击下一张
+xia.addEventListener('click',function(){
+ i++;
+ if (i>=data.length) {
+ i=0;
+ }
+ nb()
+});
+//点击上一张
+shan.addEventListener('click',function(){
+
+ if (i<=0) {
+ i=data.length;
+ }
+ i--;
+ nb()
+});
+```
\ No newline at end of file
diff --git "a/05 \350\260\242\351\223\226\346\265\251/11\346\234\21010\346\227\245\344\275\234\344\270\232.md" "b/05 \350\260\242\351\223\226\346\265\251/11\346\234\21010\346\227\245\344\275\234\344\270\232.md"
new file mode 100644
index 0000000..ac9dbeb
--- /dev/null
+++ "b/05 \350\260\242\351\223\226\346\265\251/11\346\234\21010\346\227\245\344\275\234\344\270\232.md"
@@ -0,0 +1,221 @@
+```
+
+
+
+
+
+
+
+
+
+
+
+
+ - 国际大牌◆
+ - 国妆名牌◆
+ - 清洁用品◆
+ - 男士精品
+
+
+
+

+
+
+

+
+
+

+
+
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 手风琴
+
+
+
+
+
+
+
+
+
+```
\ No newline at end of file
diff --git "a/05 \350\260\242\351\223\226\346\265\251/11\346\234\2101\346\227\245\344\275\234\344\270\232.md" "b/05 \350\260\242\351\223\226\346\265\251/11\346\234\2101\346\227\245\344\275\234\344\270\232.md"
new file mode 100644
index 0000000..5149622
--- /dev/null
+++ "b/05 \350\260\242\351\223\226\346\265\251/11\346\234\2101\346\227\245\344\275\234\344\270\232.md"
@@ -0,0 +1,39 @@
+```
+
+
+
+
+
+
+```
\ No newline at end of file
diff --git "a/05 \350\260\242\351\223\226\346\265\251/11\346\234\21021\346\227\245\344\275\234\344\270\232.md" "b/05 \350\260\242\351\223\226\346\265\251/11\346\234\21021\346\227\245\344\275\234\344\270\232.md"
new file mode 100644
index 0000000..64c426e
--- /dev/null
+++ "b/05 \350\260\242\351\223\226\346\265\251/11\346\234\21021\346\227\245\344\275\234\344\270\232.md"
@@ -0,0 +1,82 @@
+```
+
+```
\ No newline at end of file
diff --git "a/05 \350\260\242\351\223\226\346\265\251/11\346\234\21030\346\227\245.md" "b/05 \350\260\242\351\223\226\346\265\251/11\346\234\21030\346\227\245.md"
new file mode 100644
index 0000000..1778d0c
--- /dev/null
+++ "b/05 \350\260\242\351\223\226\346\265\251/11\346\234\21030\346\227\245.md"
@@ -0,0 +1,166 @@
+## 登入
+
+```
+
+```
+
+## 注册
+
+```
+
+```
+
+## 首页
+
+```
+
+```
\ No newline at end of file
diff --git "a/05 \350\260\242\351\223\226\346\265\251/11\346\234\2107\346\227\245\344\275\234\344\270\232.md" "b/05 \350\260\242\351\223\226\346\265\251/11\346\234\2107\346\227\245\344\275\234\344\270\232.md"
new file mode 100644
index 0000000..f359996
--- /dev/null
+++ "b/05 \350\260\242\351\223\226\346\265\251/11\346\234\2107\346\227\245\344\275\234\344\270\232.md"
@@ -0,0 +1,166 @@
+```
+
+
+
+
+
+
+
+ 轮播图点击切换
+
+
+
+
+
+
+

+
+
+
+
+
+
+
+```
\ No newline at end of file
diff --git "a/05 \350\260\242\351\223\226\346\265\251/11\346\234\2108\346\227\245\344\275\234\344\270\232.md" "b/05 \350\260\242\351\223\226\346\265\251/11\346\234\2108\346\227\245\344\275\234\344\270\232.md"
new file mode 100644
index 0000000..d3637fe
--- /dev/null
+++ "b/05 \350\260\242\351\223\226\346\265\251/11\346\234\2108\346\227\245\344\275\234\344\270\232.md"
@@ -0,0 +1,31 @@
+```
+// 1. 获取元素
+ let img=document.querySelector('.slider-wrapper img');
+ let p=document.querySelector('.slider-footer p');
+ let colo=document.querySelector('.slider-footer');
+
+ let n=0;
+ // 2. 开启定时器
+ let i=setInterval(function () {
+ // 数组随机数 Math.floor(Math.random()*数组名字.length);
+ // let rand=Math.floor(Math.random()*sliderData.length);
+ // 随机数对应的那个数组对象
+ // 取得图片地址,文字内容,颜色值
+ n++;
+ if (n>=sliderData.length) {
+ n=0;
+ }
+
+ // 分别修改图片,文字和颜色
+ img.src=sliderData[n].url;
+ p.innerHTML=sliderData[n].title;
+ colo.style.backgroundColor=sliderData[n].color;
+ // 改变小圆点
+ const li=document.querySelector(`.slider-indicator li:nth-child(${n+1})`);
+ // 先清除原有样式
+ document.querySelector(`.active`).classList.remove('active');
+ // 新添加
+ li.classList.add('active');
+
+ },1000);
+```
\ No newline at end of file
diff --git "a/05 \350\260\242\351\223\226\346\265\251/12.1.md" "b/05 \350\260\242\351\223\226\346\265\251/12.1.md"
new file mode 100644
index 0000000..1f50348
--- /dev/null
+++ "b/05 \350\260\242\351\223\226\346\265\251/12.1.md"
@@ -0,0 +1,498 @@
+`js
+
+#### 1. 作用域
+
+规定了变量能够被访问的 “范围”
+
+**局部作用域**
+
+- 函数作用域:
+ - 在函数内部声明的变量,外部无法直接访问
+ - 函数的参数也是函数内部的局部变量
+ - 不同函数内部声明的变量无法互相访问
+ - 函数执行完毕后,函数内部的变量实际被清空了
+- 块作用域:
+ - 使用 {} 包裹的代码为代码块,其内部声明的变量,外部无法访问
+ - let 声明的变量会产生块作用域,var 不会产生块作用域
+ - const 声明的常量也会产生块作用域
+ - 不同代码块之间的变量无法互相访问
+
+**全局作用域**
+
+script 标签和 .js文件的【最外层】就是全局作用域
+
+**作用域链**
+
+本质上是底层的==变量查找机制==
+
+- 在函数执行时,会==优先查找当前==函数作用域中的变量
+- 如果当前作用域查不到则会依次==逐级查找父级作用域==直到全局作用域
+
+总结:
+
+- 嵌套关系的作用域串联起来形成2了作用域链
+- 相同作用域链中按着从小到大的规则查找变量
+- 子作用域能够访问父作用域,父级作用域无法访问子级作用域
+
+**垃圾回收机制**(生命周期)
+
+- 内存分配:当我们声明变量、函数、对象的时候,系统会自动为它们分配内存
+- 内存使用:即读写内存,也就是使用变量、函数等
+- 内存回收:使用完毕,由==垃圾回收器==自动回收不再使用的内存
+
+说明:全局变量一般在关闭页面后回收,局部变量不用了就会自动回收
+
+内存泄漏:程序中分配的==内存==由于某种原因程序==未释放==或==无法释放==叫做==内存泄漏==
+
+**闭包**
+
+概念:一个函数对周围状态的引用捆绑在一起,内层函数中访问到其外层函数的作用域
+
+简单理解:闭包 = 内层函数 + 外层函数的变量 ==可能会有内存泄漏的问题==
+
+```
+//内部使用外部
+function outer(){
+ const a = 10
+ function fn(){
+ log(a) // 内部函数使用外部变量
+ }
+ fn()
+}
+outer()
+//外部使用内部
+function outer(){
+ const a = 10
+ function fn(){
+ log(a)
+ }
+ return fn //将内部函数,返回给外部函数
+}
+const fun = outer() //拿变量接收内部函数
+fun() //调用内部函数
+```
+
+实现数据的私有:防止 i 被修改,如果 i 定义在函数外面,全局变量容易被改,不安全
+
+```
+function fn(){
+ let i = 1
+ function fun(){
+ i++
+ log(`函数被调用了${i}次`)
+ }
+ return fun
+}
+const result = fn()
+result() // 2
+result() // 3
+```
+
+**变量提升**
+
+```
+//1.把所有 var 声明的变量提升到 当前作用域的最前面
+//2.只提升变量声明,不提升变量赋值
+log(num+'件') // undefined件
+var num = 10
+log(num) // 10
+
+//相当于
+var num
+log(num+'件')
+num = 10
+log(num)
+```
+
+#### 2. 函数进阶
+
+**函数提升**
+
+```
+//1. 会把所有函数声明提升到当前作用域的最前面
+//2. 只提升函数声明,不提升函数调用
+fn()
+function fn(){
+ log('函数提升')
+}
+```
+
+总结:
+
+- 函数提升能够使函数的声明调用更灵活
+- 函数表达式不存在提升
+- 函数提升出现在当前作用域当中
+
+**函数参数**
+
+- **动态参数:arguments** 是函数内部内置的伪数组,它包含调用函数时传入的所有实参
+
+```
+function getSum(){
+ let sum = 0
+ for(let i = 0;i <= arguments.length;i++){
+ sum = sum + arguments[i]
+ }
+ log(sum) // 35
+}
+getSum(5,10,20)
+```
+
+总结:
+
+- arguments 是个伪数组,只存在于函数中
+- arguments 的作用是动态获取函数的实参
+- 可以通过 for 循环依次得到传递过来的实参
+
+**剩余参数**(类似java的可变参数 …num)
+
+- 允许我们将一个不定数量的参数表示为一个**真数组**(常用)
+
+```
+// 表示前两个实参被a和b形参接收,后面的实参被arr数组接收
+function getSum(a,b,...arr){
+ log(arr)
+}
+getSum(1,2) // []
+getSum(1,2,3,4,5) // [3,4,5]
+```
+
+**展开运算符**:可以展开数组
+
+```
+const arr1 = [1,2,3]
+log(...arr) // 1 2 3 ...arr1 === 1,2,3
+//1.求数组中的最大值
+//log(Math.max(1,2,3))
+log(Math.max(...arr1)) // 3
+//2.合并数组
+const arr2 = [4,5,6]
+const arr =[...arr1, ...arr2]
+log(arr) // [1,2,3,4,5,6]
+```
+
+**箭头函数(重要)**
+
+- 需要匿名函数或函数表达式的地方,更适用箭头函数,可以简化代码
+
+基本语法
+
+```
+/*
+const fn = function(){
+ log(123)
+}
+*/
+//1.箭头函数,基本语法
+const fn = () => {
+ log(123)
+}
+//2.只有一个形参的时候,可以省略小括号
+const fn = x => {
+ return x + x
+}
+fn(1)
+//3.只有一行执行代码的时候,大括号和 return
+const fn = x => x + x
+log(fn(1)) //2
+//4.箭头函数可以直接返回一个对象
+const fn = (uname) => ({uname:uname})
+fn('pink老师')
+```
+
+箭头函数参数:没有 arguments 动态参数,但是有==剩余参数== …args
+
+箭头函数 this:不会创建自己的 this,它只会从作用域链的上一层找
+
+```
+const obj = {
+ uname:'pink老师'
+ sayHi:function(){
+ let i = 10
+ const count = () => {
+ log(this) //此时this指向obj
+ }
+ count()
+ }
+}
+obj.sayHi
+```
+
+#### 3. 解构赋值
+
+- 将数组的单元值快速批量,赋值给一系列变量的简洁语法
+
+**数组解构**
+
+```
+// 将数组中的值依次赋值给变量
+const arr = [100,60,80]
+// const max = arr[0]
+// const min = arr[1]
+// const avg = arr[2]
+const [max,min,avg] = arr
+// 典型应用,交换2个变量
+let a = 1
+// 立即执行函数、数组开头时,前面有代码要加分号,不然会和前面语句连在一起执行
+let b = 2;
+[b,a] = [a,b]
+log(a,b) // 2 1
+//1. 变量多,单元值少,变量undefined
+const [a,b,c,d] = [1,2,3]
+//2. 变量少,单元格多
+const [a,b] = [1,2,3]
+//3. 剩余参数,变量少,单元值多
+const [a,b, ...c] = [1,2,3,4,5]
+//4. 防止 undefined 传递(给变量赋默认值)
+const [a = 0,b = 0] = []
+const [a = 0,b = 0] = [1,2] //覆盖默认值
+```
+
+**对象解构**
+
+```
+const obj = {
+ uname: 'pink老师',
+ age: 18
+}
+//1. 对象解构语法
+//要求:变量名必须与属性名一致
+// const {uname,age} = obj
+const {uname,age} = {uname: 'pink老师',age: 18}
+log(uname,age)
+// 解构的变量名,可以重新该值
+const {uname: username,age} = {uname: 'pink老师',age: 18}
+log(username,age)
+//2. 数组对象解构
+const pig = [
+ {
+ uname: '佩奇',
+ age: 6
+ }
+]
+const [{uname,age}] = pig
+//3. 多级对象解构
+//要求:指名是哪个对象
+const pig = {
+ uname: '佩奇',
+ family: {
+ mother: '猪妈妈'
+ father: '猪爸爸'
+ brother: '乔治'
+ },
+ age: 6
+}
+const {uname,family: {mother,father,brother},age} = pig
+```
+
+**forEach 方法(适合遍历数组对象)**
+
+与 map 方法 语法相同,但是 map 会返回一个新的数组,forEach 不会
+
+```
+遍历的数组.forEach(function(当前数组元素,当前元素索引){
+ //函数体
+})
+```
+
+**filter 方法(重点)**
+
+主要使用场景:==筛选数组符合条件的元素==,并返回筛选之后的新数组
+
+```
+const arr = [10,20,30]
+const newArr = arr.filter(function(item,index){
+ return item >= 20
+})
+log(newArr) // [20,30]
+// 箭头函数写法
+const newArr = arr.filter(item => item >= 20)
+```
+
+#### 4.深入对象
+
+**构造函数**:是一种特殊的函数,主要用来初始化对象
+
+使用场景:==多个对象有相同属性,封装成一个构造函数==
+
+```
+// 创建一个构造函数,首字母要大写
+function Pig(uname,age){
+ this.uname = uname
+ this.age = age
+}
+// 创建对象
+const p1 = new Pig('佩奇',6)
+const p2 = new Pig('乔治',4)
+```
+
+实例成员:通过构造函数创建的对象称之为实例对象,==实例对象中==的属性和方法称之为==实例成员==(实例属性和实例方法)
+
+- 为构造函数传入参数,创建结构相同但值不同的对象
+- 构造函数创建的实例对象彼此独立互不影响
+
+静态成员:构造函数的属性和方法被称为静态成员(静态属性和静态方法)
+
+- 静态成员只能构造函数访问
+- 静态方法中 this 指向构造函数
+
+```
+// 静态成员
+function Pig(name){
+ this.name = name
+}
+Pig.eyes = 2 // 静态属性
+Pig.sayHi = function(){
+ log(this)
+}
+Pig.sayHi() // 指向构造函数
+log(Pig.eyes) // 2
+```
+
+#### 5.内置构造函数
+
+其实字符串。数值。布尔等基本数据类型也都有专门的构造函数,称为包装类型
+
+**Object**
+
+object 是内置的构造函数,用于创建普通对象
+
+三个常用静态方法:
+
+- **Object.keys** 获取对象中的所有属性(键),返回数组
+- **Object.keys** 获取对象中的所有属性值(值),返回数组
+- **Object.assign** 常用于对象拷贝
+
+```
+const o = {uname: 'pink',age: 18}
+log(Object.keys(o)) // [uname,age]
+log(Object.values(o)) // ['pink',18]
+// 拷贝
+const oo = {}
+Object.assign(oo,o) // 将 o 对象拷贝给 oo 对象
+// 给对象追加属性
+Object.assign(o,{sex: '男'})
+log(o) // [uname: 'pink',age: 18,sex: '男']
+```
+
+**Array**
+
+Array 是内置构造函数,用于创建数组
+
+常用实例方法:
+
+| 方法 | 作用 | 说明 |
+| ----------- | -------- | ---------------------------------------------------- |
+| **forEach** | 遍历数组 | 不返回数组,经常用于==查找遍历数组元素== |
+| **filter** | 过滤数组 | ==返回新数组==,返回==筛选满足条件==的数组元素 |
+| **map** | 迭代数组 | ==放回新数组==,返回==处理之后==的数组元素 |
+| **reduce** | 累计器 | 返回累计处理的结果,经常用于求和等 |
+| **find** | 查找元素 | 返回符合条件的第一个数组元素值,没则有返回undefined |
+| **every** | 检查数组 | 检查数组中所有元素,都满足某个条件,返回 true或false |
+| **some** | 检查数组 | 检查数组中所有元素,有元素满足条件,返回 true或false |
+| **concat** | 合并数组 | 合并两个数组,返回一个新数组 |
+| **sort** | 排序数组 | 对原数组单元值进行排序 |
+| **reverse** | 反转数组 | 将数组反转 |
+
+```
+// 数组 reduce 方法
+const arr = [1,5,8]
+//1. 没有初始值
+const total = arr.reduce(function(prev,current){
+ return prev + current //上一次的值 + 当前的值
+})
+log(total) // 14
+//2. 有初始值
+const total = arr.reduce(function(prev,current){
+ return prev + current //上一次的值 + 当前的值
+}.10)
+log(total) // 24
+//3. 箭头函数写法
+const total = arr.reduce((prev,current) => prev + current, 10)
+```
+
+案例:有一个员工数组对象,计算当月支出多少薪资
+
+```
+const arr =[
+ {
+ uname: '张三',
+ salary: 10000
+ }, {
+ uname: '李四',
+ salary: 10000
+ }, {
+ uname: '王五',
+ salary: 10000
+ }
+]
+//一定要有初始值,否则默认第一个对象为初始值
+const total = arr.reduce((prev,current) => prev + current.salary, 0)
+log(total) // 30000
+```
+
+静态方法 **Array.from(数组)** 将伪数组转换为真数组
+
+```
+const lis = document.querySelectorAll('ul li')
+const liArr = Array.from(lis)
+```
+
+**String**
+
+常见实例方法1:
+
+| 方法 | 说明 |
+| --------------------------------------- | --------------------------------------------- |
+| **split(’分隔符’)** | 将字符串转换为数组,和 join() 相反 |
+| **substring(起始索引,结束索引)** | 截取字符串 |
+| **startswith(检查字符串,检测开始索引)** | 检测是否以某字符开头,返回布尔值,endwith相反 |
+| **includes(搜索的字符串,位置索引)** | 判断一个字符串是否包含某个字符 |
+
+**Number**
+
+ **toFixed()** 设置保留小数位的长度
+
+````
+const num = 10.923
+log(num.toFixed(1)) //10.9
+log(num.toFixed(2)) //10.92
+log(num.toFixed()) //11 四舍五入
+```
+
+# 作业
+```js
+//错误
+
+
+````
\ No newline at end of file
diff --git "a/05 \350\260\242\351\223\226\346\265\251/12.11.md" "b/05 \350\260\242\351\223\226\346\265\251/12.11.md"
new file mode 100644
index 0000000..93cb06a
--- /dev/null
+++ "b/05 \350\260\242\351\223\226\346\265\251/12.11.md"
@@ -0,0 +1,156 @@
+```
+/**
+ * 目标1:渲染图书列表
+ * 1.1 获取数据
+ * 1.2 渲染数据
+ */
+const creator = ''
+// 封装-获取并渲染图书列表函数
+function getBooksList() {
+ // 1.1 获取数据
+ axios({
+ url: 'http://hmajax.itheima.net/api/books',
+ params: {
+ // 外号:获取对应数据
+ creator
+ }
+ }).then(result => {
+ // console.log(result)
+ const bookList = result.data.data;
+ // console.log(bookList)
+ // 1.2 渲染数据
+ const htmlStr = bookList.map((item, index) => {
+ return `
+ | ${index + 1} |
+ ${item.bookname} |
+ ${item.author} |
+ ${item.publisher} |
+
+ 删除
+ 编辑
+ |
+
`
+ }).join('')
+ // console.log(htmlStr)
+ document.querySelector('.list').innerHTML = htmlStr
+ })
+}
+// 网页加载运行,获取并渲染列表一次
+getBooksList()
+
+/**
+ * 目标2:新增图书
+ * 2.1 新增弹框->显示和隐藏
+ * 2.2 收集表单数据,并提交到服务器保存
+ * 2.3 刷新图书列表
+ */
+// 2.1 创建弹框对象
+const addModalDom = document.querySelector('.add-modal')
+const addModal = new bootstrap.Modal(addModalDom)
+// 保存按钮->点击->隐藏弹框
+document.querySelector('.add-btn').addEventListener('click', () => {
+ // 2.2 收集表单数据,并提交到服务器保存
+ const addForm = document.querySelector('.add-form')
+ const bookObj = serialize(addForm, { hash: true, empty: true })
+ // console.log(bookObj)
+ // 提交到服务器
+ axios({
+ url: 'http://hmajax.itheima.net/api/books',
+ method: 'POST',
+ data: {
+ ...bookObj,
+ creator
+ }
+ }).then(result => {
+ // console.log(result)
+ // 2.3 添加成功后,重新请求并渲染图书列表
+ getBooksList()
+ // 重置表单
+ addForm.reset()
+ // 隐藏弹框
+ addModal.hide()
+ })
+})
+
+/**
+ * 目标3:删除图书
+ * 3.1 删除元素绑定点击事件->获取图书id
+ * 3.2 调用删除接口
+ * 3.3 刷新图书列表
+ */
+// 3.1 删除元素->点击(事件委托)
+document.querySelector('.list').addEventListener('click', e => {
+ // 获取触发事件目标元素
+ // console.log(e.target)
+ // 判断点击的是删除元素
+ if (e.target.classList.contains('del')) {
+ // console.log('点击删除元素')
+ // 获取图书id(自定义属性id)
+ const theId = e.target.parentNode.dataset.id
+ // console.log(theId)
+ // 3.2 调用删除接口
+ axios({
+ url: `http://hmajax.itheima.net/api/books/${theId}`,
+ method: 'DELETE'
+ }).then(() => {
+ // 3.3 刷新图书列表
+ getBooksList()
+ })
+ }
+})
+
+/**
+ * 目标4:编辑图书
+ * 4.1 编辑弹框->显示和隐藏
+ * 4.2 获取当前编辑图书数据->回显到编辑表单中
+ * 4.3 提交保存修改,并刷新列表
+ */
+// 4.1 编辑弹框->显示和隐藏
+const editDom = document.querySelector('.edit-modal')
+const editModal = new bootstrap.Modal(editDom)
+// 编辑元素->点击->弹框显示
+document.querySelector('.list').addEventListener('click', e => {
+ // 判断点击的是否为编辑元素
+ if (e.target.classList.contains('edit')) {
+ // 4.2 获取当前编辑图书数据->回显到编辑表单中
+ const theId = e.target.parentNode.dataset.id
+ axios({
+ url: `http://hmajax.itheima.net/api/books/${theId}`
+ }).then(result => {
+ const bookObj = result.data.data
+ // document.querySelector('.edit-form .bookname').value = bookObj.bookname
+ // document.querySelector('.edit-form .author').value = bookObj.author
+ // 数据对象“属性”和标签“类名”一致
+ // 遍历数据对象,使用属性去获取对应的标签,快速赋值
+ const keys = Object.keys(bookObj) // ['id', 'bookname', 'author', 'publisher']
+ keys.forEach(key => {
+ document.querySelector(`.edit-form .${key}`).value = bookObj[key]
+ })
+ })
+ editModal.show()
+ }
+})
+// 修改按钮->点击->隐藏弹框
+document.querySelector('.edit-btn').addEventListener('click', () => {
+ // 4.3 提交保存修改,并刷新列表
+ const editForm = document.querySelector('.edit-form')
+ const { id, bookname, author, publisher } = serialize(editForm, { hash: true, empty: true})
+ // 保存正在编辑的图书id,隐藏起来:无需让用户修改
+ //
+ axios({
+ url: `http://hmajax.itheima.net/api/books/${id}`,
+ method: 'PUT',
+ data: {
+ bookname,
+ author,
+ publisher,
+ creator
+ }
+ }).then(() => {
+ // 修改成功以后,重新获取并刷新列表
+ getBooksList()
+ // 隐藏弹框
+ editModal.hide()
+ })
+})
+```
\ No newline at end of file
diff --git "a/05 \350\260\242\351\223\226\346\265\251/12.12.md" "b/05 \350\260\242\351\223\226\346\265\251/12.12.md"
new file mode 100644
index 0000000..e05d714
--- /dev/null
+++ "b/05 \350\260\242\351\223\226\346\265\251/12.12.md"
@@ -0,0 +1,30 @@
+```
+// 1. 定义myAxios函数,接收配置对象,返回Promise对象
+function myAxios(config) {
+ return new Promise((resolve, reject) => {
+ // 2. 发起XHR请求,默认请求方法为GET
+ const xhr = new XMLHttpRequest()
+ xhr.open(config.method || 'GET', config.url)
+ xhr.addEventListener('loadend', () => {
+ // 3. 调用成功/失败的处理程序
+ if (xhr.status >= 200 && xhr.status < 300) {
+ resolve(JSON.parse(xhr.response))
+ } else {
+ reject(new Error(xhr.response))
+ }
+ })
+ xhr.send()
+ })
+}
+
+// 4. 使用myAxios函数,获取省份列表展示
+myAxios({
+ url: 'http://hmajax.itheima.net/api/province'
+}).then(result => {
+ console.log(result)
+ document.querySelector('.my-p').innerHTML = result.list.join('
')
+}).catch(error => {
+ console.log(error)
+ document.querySelector('.my-p').innerHTML = error.message
+})
+```
\ No newline at end of file
diff --git "a/05 \350\260\242\351\223\226\346\265\251/12.13.md" "b/05 \350\260\242\351\223\226\346\265\251/12.13.md"
new file mode 100644
index 0000000..e6fe011
--- /dev/null
+++ "b/05 \350\260\242\351\223\226\346\265\251/12.13.md"
@@ -0,0 +1,165 @@
+# 作业
+
+```
+const creator = 'cheng';
+
+function render() {
+ $.ajax({
+ url: 'https://hmajax.itheima.net/api/books',
+ type: 'get',
+ data: {
+ creator
+ },
+ success: (result) => {
+ const data = result.data;
+ $('tbody').html(
+ data.map((item, index) => {
+ const {id, bookname, author, publisher} = item;
+ return `
+ | ${index + 1} |
+ ${bookname} |
+ ${author} |
+ ${publisher} |
+
+ 删除
+ 编辑
+ |
+
`
+ }).join(''))
+ },
+ error: error => {
+ console.log(error)
+ }
+ })
+
+}
+
+render();
+const addModal = $('.add-modal')[0];
+const newAddModal = new bootstrap.Modal(addModal)
+//添加里的保存单机事件
+$('.add-btn').bind('click', () => {
+ const form = $('.add-form')[0];
+ const book = serialize(form, {hash: true, empty: true});
+ $.ajax({
+ url: 'https://hmajax.itheima.net/api/books',
+ type: 'post',
+ data: {
+ creator,
+ ...book
+ },
+ success: () => {
+ form.reset();
+ newAddModal.hide();
+ render();
+ },
+ error: (error) => {
+ console.log(error)
+ }
+ }
+ )
+
+})
+//删除单机事件
+$('tbody ').on('click', '.del', function () {
+ const id = $(this).parent().data('id');
+ if (!confirm('是否要删除')) {
+ return 0;
+ } else {
+ $.ajax({
+ url: 'https://hmajax.itheima.net/api/books/' + id,
+ type: 'delete',
+ success: () => {
+ render();
+ },
+ error: (error) => {
+ console.log(error);
+ }
+ })
+ }
+}).on('click', '.edit', function () {
+ const id = $(this).parent().data('id');
+ const editModal = $('.edit-modal');
+ const newModal = new bootstrap.Modal(editModal);
+ newModal.show();
+ const form = $('.edit-form')[0];
+ $.ajax({
+ url: 'https://hmajax.itheima.net/api/books/' + id,
+ type: 'get',
+ success: (result) => {
+ const {bookname, author, publisher} = result.data
+ $('.bookname')[1].value = bookname;
+ $('.author')[1].value = author;
+ $('.publisher')[1].value = publisher;
+ },
+ error: (error) => {
+ console.log(error)
+ }
+ })
+ $('.edit-btn').bind('click', () => {
+ const book = serialize(form, {hash: true, empty: true});
+ console.log(book)
+ $.ajax({
+ url: "https://hmajax.itheima.net/api/books/" + id,
+ type: 'put',
+ data: {
+ creator,
+ ...book,
+ },
+ success: () => {
+ newModal.hide();
+ render();
+ },
+ error: (error) => {
+ console.log(error)
+ }
+ })
+ })
+})
+function getSliderData(index) {
+ let newIndex = index % sliderData.length;
+ let a = sliderData[newIndex % sliderData.length];
+ $('.slider-wrapper img')[0].src = a.url;
+ $('.slider-footer p')[0].innerHTML = a.title;
+ $('.slider-footer')[0].style.backgroundColor = a.color;
+ $('.slider-indicator .active')[0].classList.remove('active');
+ $('.slider-indicator li')[newIndex].classList.add('active');
+}
+
+let index = 0;
+
+let interval = setInterval(function () {
+ getSliderData(index);
+ index++;
+}, 1000)
+function prev() {
+ index--;
+ if (index <= 0) {
+ index = sliderData.length
+ }
+ getSliderData(index);
+}
+
+function next() {
+ index++;
+ getSliderData(index);
+}
+
+
+$('.toggle').on('click', '.prev', function () {
+ prev();
+}).on('click', '.next', function () {
+ next();
+})
+
+$('tbody').ready(
+ $('.slider').mouseenter(function (){
+ console.log(123)
+ clearInterval(interval);
+}).mouseleave(function (){
+ interval=setInterval(function () {
+ index++;
+ getSliderData(index);
+ }, 1000)
+ }));
+```
\ No newline at end of file
diff --git "a/05 \350\260\242\351\223\226\346\265\251/12.14.md" "b/05 \350\260\242\351\223\226\346\265\251/12.14.md"
new file mode 100644
index 0000000..5b83289
--- /dev/null
+++ "b/05 \350\260\242\351\223\226\346\265\251/12.14.md"
@@ -0,0 +1,243 @@
+# 练习
+
+```
+// 1. 给 ul 添加点击事件(事件委托)
+$('ul').on('click','a',function(){
+ // 先删除 li里的 active
+ $('a.active').removeClass('active')
+ // 自己添加 active 类
+ $(this).addClass('active')
+
+ // 先删除 有item类 里的 active
+ $('.item.active').removeClass('active')
+ // 获取当前点击的 a 的索引
+ const id = $('a').index($(this))
+ // 根据 id 指定某个div添加 active 类
+ $(`.item:eq(${id})`).addClass('active')
+})
+~~~
+
+### 轮播图
+
+~~~ js
+// 定义起始值
+let i = 0
+// 1. 给 > 按钮 添加点击事件
+$('.next').bind('click', () => {
+ // 判断 i 是否大于数组长度
+ i = i >= sliderData.length - 1 ? 0 : i + 1
+ // 调用切换函数
+ toggleData()
+})
+
+// 2. 给 < 按钮添加点击事件
+$('.prev').bind('click', () => {
+ // 判断 i 是否大于数组长度
+ i = i <= 0 ? sliderData.length - 1 : i - 1
+ // 调用切换函数
+ toggleData()
+})
+
+// 3. 添加定时器
+let time = setInterval(() => {
+ $('.next').click()
+}, 1000)
+
+// 4. 添加 鼠标经过、移出事件
+$('.slider-wrapper,.slider-footer').bind({
+ 'mouseover': () => {
+ // console.log(111);
+ // 暂停定时器
+ clearInterval(time)
+ },
+ 'mouseout': () => {
+ // console.log(222);
+ // 开启定时器
+ time = setInterval(() => {
+ $('.next').click()
+ }, 1000)
+ }
+})
+
+// 分装一个切换(图片、标题、背景颜色、小圆点)的类
+function toggleData() {
+ // 切换图片
+ $('.slider-wrapper img').attr('src', sliderData[i].url)
+ // 切换标题
+ $('.slider-footer p').html(sliderData[i].title)
+ // 切换标题背景颜色
+ $('.slider-footer').css('background', sliderData[i].color)
+ // 切换小圆点
+ // 先删除 active 类
+ $('.slider-indicator li.active').removeClass('active')
+ // 自己添加 active 类
+ $(`.slider-indicator li:eq(${i})`).addClass('active')
+}
+/**
+ * 目标一: 获取接口数据并渲染
+ * 1.1 定义自己的外号
+ * 1.2 通过自己的外号,发送异步请求,获取数据
+ * 1.3 将获取的数据渲染
+ */
+
+// 1.1 定义自己的外号
+const creator = '墨下皆是心酸'
+
+// 因为,添加、删除、编辑后都要渲染一遍,所有分装一个渲染函数
+function getBooksList() {
+ // 1.2 通过自己的外号,发送异步请求,获取数据
+ $.ajax({
+ url: 'https://hmajax.itheima.net/api/books',
+ data: {
+ creator
+ },
+ success: (result) => {
+ const data = result.data
+ // 将获取的数据渲染到页面上
+ const htmlStr = $.map(data, (item, index) => {
+ // 解构数据
+ const { id, bookname, author, publisher } = item
+ return `
+
+ | ${index + 1} |
+ ${bookname} |
+ ${author} |
+ ${publisher} |
+
+ 删除
+ 编辑
+ |
+
+ `
+ }).join('')
+ $('tbody').html(htmlStr)
+ }
+ })
+}
+getBooksList()
+
+
+/**
+ * 目标二:添加图书
+ * 2.1 获取添加弹框d对象
+ * 2.2 给保存按钮添加点击事件,收集表单信息,隐藏弹框
+ * 2.3 通过获取的表单内容,发送异步请求
+ * 2.4 清空表单,刷新图书列表
+*/
+
+// 2.1 获取 添加弹框 对象
+const addModal = new bootstrap.Modal($('.add-modal'))
+
+// 2.2 给保存按钮添加点击事件,收集表单信息,隐藏弹框
+$('.add-btn').bind('click', () => {
+ // 获取 添加弹框 中的表单对象
+ const addForm = $('.add-form')[0]
+ // 使用表单插件,获取表单信息
+ const objBook = serialize(addForm, { hash: true, empty: true })
+ console.log(objBook);
+ // 2.3 通过获取的表单内容,发送异步请求
+ $.ajax({
+ url: 'https://hmajax.itheima.net/api/books',
+ type: 'post',
+ data: {
+ ...objBook,
+ creator
+ },
+ success: () => {
+ // 2.4 清空表单,刷新图书列表
+ // console.log(result);
+ // 刷新图书列表
+ getBooksList()
+ // 隐藏 添加弹框
+ addModal.hide()
+ // 清空表单
+ addForm.reset()
+ }
+ })
+})
+
+
+/**
+ * 目标三:删除图书
+ * 3.1 给 tbody 添加点击事件(事件委托)
+ * 3.2 通过自定义属性,向接口发送异步请求,删除图书
+ * 3.3 刷新图书列表
+ */
+
+$('tbody').on('click', '.del', function () {
+ // 是否删除弹框(提高数据安全性)
+ if (confirm('你确定要删除吗?')) {
+ // 获得父级身上的自定义属性
+ const id = $(this).parent().data('id')
+ // console.log(id);
+ // 3.2 通过自定义属性,向接口发送异步请求,删除图书
+ $.ajax({
+ url: `https://hmajax.itheima.net/api/books/${id}`,
+ type: 'delete',
+ success: () => {
+ // 3.3 刷新图书列表
+ getBooksList()
+ }
+ })
+ }
+})
+
+
+/**
+ * 目标四:修改图书
+ * 4.1 给 tbody 添加点击事件(事件委托),显示弹框
+ * 4.2 通过 id 发送异步请求,获取当前图书的信息,回显在表单上
+ * 4.3 点击 修改 将修改后的数据提交给异步请求,隐藏弹框,刷新表单页面
+ */
+
+
+// 获取 编辑弹框对象
+const editModal = new bootstrap.Modal($('.edit-modal'))
+// 4.1 给 tbody 添加点击事件(事件委托),显示弹框
+$('tbody').on('click', '.edit', function () {
+ // 获得父级身上的自定义属性
+ const id = $(this).parent().data('id')
+ // 4.2 通过 id 发送异步请求,获取当前图书的信息,回显在表单上
+ $.ajax({
+ url: `https://hmajax.itheima.net/api/books/${id}`,
+ success: result => {
+ // 因为,获取到的数据的 key 名刚好是每个表单的 类名
+ // 所以,可以先获取响应数据中的所有 key,遍历回显
+ const bookInfo = result.data
+ // console.log(bookInfo);
+ const keys = Object.keys(bookInfo)
+ // console.log(keys);
+ keys.forEach(key => {
+ document.querySelector(`.edit-form .${key}`).value = bookInfo[key]
+ })
+ // 显示弹框
+ editModal.show()
+ }
+ })
+})
+
+
+// 获取编辑弹框中的表单对象
+const editForm = $('.edit-form')[0]
+// 4.3 点击 修改 将修改后的数据提交给异步请求,隐藏弹框,刷新表单页面
+$('.edit-btn').bind('click', () => {
+ // 使用插件获取表单信息,并解构
+ const objBook = serialize(editForm, { hash: true, empty: true })
+ // console.log(objBook);
+ // 将修改后的数据提交给异步请求
+ $.ajax({
+ url: `https://hmajax.itheima.net/api/books/${objBook.id}`,
+ type: 'put',
+ data: {
+ ...objBook,
+ creator
+ },
+ success: result => {
+ // 隐藏弹框
+ editModal.hide()
+ // 刷新图书列表
+ getBooksList()
+ }
+ })
+})
+```
\ No newline at end of file
diff --git "a/05 \350\260\242\351\223\226\346\265\251/12.6.md" "b/05 \350\260\242\351\223\226\346\265\251/12.6.md"
new file mode 100644
index 0000000..8a63170
--- /dev/null
+++ "b/05 \350\260\242\351\223\226\346\265\251/12.6.md"
@@ -0,0 +1,77 @@
+总结:
+
+1. 实例属性 `length` 用来获取字符串的度长(重点)
+2. 实例方法 `split('分隔符')` 用来将字符串拆分成数组(重点)
+3. 实例方法 `substring(需要截取的第一个字符的索引[,结束的索引号])` 用于字符串截取(重点)
+4. 实例方法 `startsWith(检测字符串[, 检测位置索引号])` 检测是否以某字符开头(重点)
+5. 实例方法 `includes(搜索的字符串[, 检测位置索引号])` 判断一个字符串是否包含在另一个字符串中,根据情况返回 true 或 false(重点)
+6. 实例方法 `toUpperCase` 用于将字母转换成大写
+7. 实例方法 `toLowerCase` 用于将就转换成小写
+8. 实例方法 `indexOf` 检测是否包含某字符
+9. 实例方法 `endsWith` 检测是否以某字符结尾
+10. 实例方法 `replace` 用于替换字符串,支持正则匹配
+11. 实例方法 `match` 用于查找字符串,支持正则匹配
+
+注:String 也可以当做普通函数使用,这时它的作用是强制转换成字符串数据类型。
+
+#### Number
+
+`Number` 是内置的构造函数,用于创建数值。
+
+```
+
+```
+
+总结:
+
+1. 推荐使用字面量方式声明数值,而不是 `Number` 构造函数
+2. 实例方法 `toFixed` 用于设置保留小数位的长度
+
+# 作业
+
+```
+function rand(arr){
+ let str=``;
+ arr.forEach(ele => {
+ let {id,icon,num,price,isChecked}=ele;
+ // console.log(ele);
+ str+=`
+
+
+
+
${price}
+
+
${price*num}
+
+
+ `
+ })
+ document.querySelector('.tbody').innerHTML=str;
+ }
+ rand(dataArr)
+ //减
+ let dad=document.querySelectorAll('.decrease');
+ dad[0].addEventListener('click',()=>{
+ console.log('-');
+ })
+ //加
+ let nan=document.querySelectorAll('.increase');
+ nan[0].addEventListener('click',()=>{
+ console.log('+');
+ })
+
+```
\ No newline at end of file
diff --git "a/05 \350\260\242\351\223\226\346\265\251/12.7.md" "b/05 \350\260\242\351\223\226\346\265\251/12.7.md"
new file mode 100644
index 0000000..b51c677
--- /dev/null
+++ "b/05 \350\260\242\351\223\226\346\265\251/12.7.md"
@@ -0,0 +1,88 @@
+```
+// 1. 渲染业务
+ const tbody = document.querySelector('.tbody')
+ const price = document.querySelector('.price')
+ const checkAll = document.querySelector('.check-all input')
+
+ function render() {
+ let total = 0
+ const strArr = dataArr.map(function (ele, index) {
+ return `
+
+
+
+
${ele.price}
+
+
+
+ ${ele.num}
+
+
+
+
${ele.price * ele.num}
+
+
+ `
+ })
+ tbody.innerHTML = strArr.join('')
+
+ // 全选按钮设置
+ checkAll.checked = dataArr.every(ele => ele.isChecked === true)
+ // 总价模块:只选择勾选的商品
+ const newArr = dataArr.filter(ele => ele.isChecked)
+
+ const totalPrice = newArr.reduce((prev, item) => prev += item.num * item.price, 0)
+ document.querySelector('.price-box .price').innerHTML = totalPrice.toFixed(2)
+ const totalNum = newArr.reduce((prev, item) => prev += item.num, 0)
+ document.querySelector('.pay').innerHTML = `结算(${totalNum})`
+ // 空空购物车是否显示
+ const empty = document.querySelector('.empty')
+ empty.style.display = dataArr.length === 0 ? 'block' : 'none'
+ }
+ render()
+
+
+ // 2. 事件委托
+ tbody.addEventListener('click', function (e) {
+ const id = e.target.parentNode.parentNode.dataset.id
+ // 删除业务
+ if (e.target.className === 'del') {
+ dataArr.splice(id, 1)
+ //渲染业务
+ render()
+ }
+ // 小复选框业务是否全选开控制总的复选框
+ if (e.target.tagName === 'INPUT') {
+ // alert(11)
+ dataArr[id].isChecked = e.target.checked
+ //渲染业务
+ render()
+ }
+
+ // 增加数量业务
+ if (e.target.className === "increase") {
+ const idNum = e.target.parentNode.parentNode.parentNode.dataset.id
+ dataArr[idNum].num++
+ render()
+ }
+ // 删除数量业务
+ if (e.target.className === "decrease") {
+ const idNum = e.target.parentNode.parentNode.parentNode.dataset.id
+ if (dataArr[idNum].num <= 1) {
+ dataArr[idNum].num = 1
+ } else {
+ dataArr[idNum].num--
+ render()
+ }
+ }
+ })
+
+ // 3. 全选反选点击
+ // 3.1 点击全选修改数组所有选中状态为true
+ checkAll.addEventListener('click', function () {
+ dataArr.forEach(ele => ele.isChecked = this.checked)
+ // console.log(dataArr)
+ // 渲染页面
+ render()
+ })
+```
\ No newline at end of file
diff --git "a/05 \350\260\242\351\223\226\346\265\251/12\346\234\2107\346\227\245.md" "b/05 \350\260\242\351\223\226\346\265\251/12\346\234\2107\346\227\245.md"
new file mode 100644
index 0000000..1c1f372
--- /dev/null
+++ "b/05 \350\260\242\351\223\226\346\265\251/12\346\234\2107\346\227\245.md"
@@ -0,0 +1,38 @@
+```
+
+```
\ No newline at end of file
diff --git "a/05 \350\260\242\351\223\226\346\265\251/20231202 \350\277\233\351\230\266 .md" "b/05 \350\260\242\351\223\226\346\265\251/20231202 \350\277\233\351\230\266 .md"
new file mode 100644
index 0000000..2b7dd64
--- /dev/null
+++ "b/05 \350\260\242\351\223\226\346\265\251/20231202 \350\277\233\351\230\266 .md"
@@ -0,0 +1,523 @@
+### 笔记
+
+##### 作用域
+
+规定了变量能够被访问的 “范围”、
+
+##### 局部作用域
+
+函数作用域:
+
+1.在函数内部声明的变量,外部无法直接访问
+
+2.函数的参数也是函数内部的局部变量
+
+3.不同函数内部声明的变量无法互相访问
+
+4.函数执行完毕后,函数内部的变量实际被清空了
+
+##### 块作用域:
+
+1.使用 {} 包裹的代码为代码块,其内部声明的变量,外部无法访问
+
+2.let 声明的变量会产生块作用域,var 不会产生块作用域
+
+3.const 声明的常量也会产生块作用域
+
+4.不同代码块之间的变量无法互相访问
+
+##### 全局作用域
+
+script 标签和 .js文件的【最外层】就是全局作用域
+
+作用域链
+
+本质上是底层的==变量查找机制==
+
+- 在函数执行时,会==优先查找当前==函数作用域中的变量
+- 如果当前作用域查不到则会依次==逐级查找父级作用域==直到全局作用域
+
+**闭包**
+
+概念:一个函数对周围状态的引用捆绑在一起,内层函数中访问到其外层函数的作用域
+
+简单理解:闭包 = 内层函数 + 外层函数的变量 ==可能会有内存泄漏的问题==
+
+```
+//内部使用外部
+function outer(){
+ const a = 10
+ function fn(){
+ log(a) // 内部函数使用外部变量
+ }
+ fn()
+}
+outer()
+//外部使用内部
+function outer(){
+ const a = 10
+ function fn(){
+ log(a)
+ }
+ return fn //将内部函数,返回给外部函数
+}
+const fun = outer() //拿变量接收内部函数
+fun() //调用内部函数
+```
+
+实现数据的私有:防止 i 被修改,如果 i 定义在函数外面,全局变量容易被改,不安全
+
+```
+function fn(){
+ let i = 1
+ function fun(){
+ i++
+ log(`函数被调用了${i}次`)
+ }
+ return fun
+}
+const result = fn()
+result() // 2
+result() // 3
+```
+
+**变量提升**
+
+```
+//1.把所有 var 声明的变量提升到 当前作用域的最前面
+//2.只提升变量声明,不提升变量赋值
+log(num+'件') // undefined件
+var num = 10
+log(num) // 10
+
+//相当于
+var num
+log(num+'件')
+num = 10
+log(num)
+```
+
+#### 2. 函数进阶
+
+**函数提升**
+
+```
+//1. 会把所有函数声明提升到当前作用域的最前面
+//2. 只提升函数声明,不提升函数调用
+fn()
+function fn(){
+ log('函数提升')
+}
+```
+
+总结:
+
+- 函数提升能够使函数的声明调用更灵活
+- 函数表达式不存在提升
+- 函数提升出现在当前作用域当中
+
+**函数参数**
+
+- **动态参数:arguments** 是函数内部内置的伪数组,它包含调用函数时传入的所有实参
+
+```
+function getSum(){
+ let sum = 0
+ for(let i = 0;i <= arguments.length;i++){
+ sum = sum + arguments[i]
+ }
+ log(sum) // 35
+}
+getSum(5,10,20)
+```
+
+总结:
+
+- arguments 是个伪数组,只存在于函数中
+- arguments 的作用是动态获取函数的实参
+- 可以通过 for 循环依次得到传递过来的实参
+
+**剩余参数**(类似java的可变参数 …num)
+
+- 允许我们将一个不定数量的参数表示为一个**真数组**(常用)
+
+```
+// 表示前两个实参被a和b形参接收,后面的实参被arr数组接收
+function getSum(a,b,...arr){
+ log(arr)
+}
+getSum(1,2) // []
+getSum(1,2,3,4,5) // [3,4,5]
+```
+
+**展开运算符**:可以展开数组
+
+```
+const arr1 = [1,2,3]
+log(...arr) // 1 2 3 ...arr1 === 1,2,3
+//1.求数组中的最大值
+//log(Math.max(1,2,3))
+log(Math.max(...arr1)) // 3
+//2.合并数组
+const arr2 = [4,5,6]
+const arr =[...arr1, ...arr2]
+log(arr) // [1,2,3,4,5,6]
+```
+
+**箭头函数(重要)**
+
+- 需要匿名函数或函数表达式的地方,更适用箭头函数,可以简化代码
+
+基本语法
+
+```
+/*
+const fn = function(){
+ log(123)
+}
+*/
+//1.箭头函数,基本语法
+const fn = () => {
+ log(123)
+}
+//2.只有一个形参的时候,可以省略小括号
+const fn = x => {
+ return x + x
+}
+fn(1)
+//3.只有一行执行代码的时候,大括号和 return
+const fn = x => x + x
+log(fn(1)) //2
+//4.箭头函数可以直接返回一个对象
+const fn = (uname) => ({uname:uname})
+fn('pink老师')
+```
+
+箭头函数参数:没有 arguments 动态参数,但是有==剩余参数== …args
+
+箭头函数 this:不会创建自己的 this,它只会从作用域链的上一层找
+
+```
+const obj = {
+ uname:'pink老师'
+ sayHi:function(){
+ let i = 10
+ const count = () => {
+ log(this) //此时this指向obj
+ }
+ count()
+ }
+}
+obj.sayHi
+```
+
+#### 3. 解构赋值
+
+- 将数组的单元值快速批量,赋值给一系列变量的简洁语法
+
+**数组解构**
+
+```
+// 将数组中的值依次赋值给变量
+const arr = [100,60,80]
+// const max = arr[0]
+// const min = arr[1]
+// const avg = arr[2]
+const [max,min,avg] = arr
+// 典型应用,交换2个变量
+let a = 1
+// 立即执行函数、数组开头时,前面有代码要加分号,不然会和前面语句连在一起执行
+let b = 2;
+[b,a] = [a,b]
+log(a,b) // 2 1
+//1. 变量多,单元值少,变量undefined
+const [a,b,c,d] = [1,2,3]
+//2. 变量少,单元格多
+const [a,b] = [1,2,3]
+//3. 剩余参数,变量少,单元值多
+const [a,b, ...c] = [1,2,3,4,5]
+//4. 防止 undefined 传递(给变量赋默认值)
+const [a = 0,b = 0] = []
+const [a = 0,b = 0] = [1,2] //覆盖默认值
+```
+
+**对象解构**
+
+```
+const obj = {
+ uname: 'pink老师',
+ age: 18
+}
+//1. 对象解构语法
+//要求:变量名必须与属性名一致
+// const {uname,age} = obj
+const {uname,age} = {uname: 'pink老师',age: 18}
+log(uname,age)
+// 解构的变量名,可以重新该值
+const {uname: username,age} = {uname: 'pink老师',age: 18}
+log(username,age)
+//2. 数组对象解构
+const pig = [
+ {
+ uname: '佩奇',
+ age: 6
+ }
+]
+const [{uname,age}] = pig
+//3. 多级对象解构
+//要求:指名是哪个对象
+const pig = {
+ uname: '佩奇',
+ family: {
+ mother: '猪妈妈'
+ father: '猪爸爸'
+ brother: '乔治'
+ },
+ age: 6
+}
+const {uname,family: {mother,father,brother},age} = pig
+```
+
+**forEach 方法(适合遍历数组对象)**
+
+与 map 方法 语法相同,但是 map 会返回一个新的数组,forEach 不会
+
+```
+遍历的数组.forEach(function(当前数组元素,当前元素索引){
+ //函数体
+})
+```
+
+**filter 方法(重点)**
+
+主要使用场景:==筛选数组符合条件的元素==,并返回筛选之后的新数组
+
+```
+const arr = [10,20,30]
+const newArr = arr.filter(function(item,index){
+ return item >= 20
+})
+log(newArr) // [20,30]
+// 箭头函数写法
+const newArr = arr.filter(item => item >= 20)
+```
+
+#### 4.深入对象
+
+**构造函数**:是一种特殊的函数,主要用来初始化对象
+
+使用场景:==多个对象有相同属性,封装成一个构造函数==
+
+```
+// 创建一个构造函数,首字母要大写
+function Pig(uname,age){
+ this.uname = uname
+ this.age = age
+}
+// 创建对象
+const p1 = new Pig('佩奇',6)
+const p2 = new Pig('乔治',4)
+```
+
+实例成员:通过构造函数创建的对象称之为实例对象,==实例对象中==的属性和方法称之为==实例成员==(实例属性和实例方法)
+
+- 为构造函数传入参数,创建结构相同但值不同的对象
+- 构造函数创建的实例对象彼此独立互不影响
+
+静态成员:构造函数的属性和方法被称为静态成员(静态属性和静态方法)
+
+- 静态成员只能构造函数访问
+- 静态方法中 this 指向构造函数
+
+```
+// 静态成员
+function Pig(name){
+ this.name = name
+}
+Pig.eyes = 2 // 静态属性
+Pig.sayHi = function(){
+ log(this)
+}
+Pig.sayHi() // 指向构造函数
+log(Pig.eyes) // 2
+```
+
+#### 5.内置构造函数
+
+其实字符串。数值。布尔等基本数据类型也都有专门的构造函数,称为包装类型
+
+**Object**
+
+object 是内置的构造函数,用于创建普通对象
+
+三个常用静态方法:
+
+- **Object.keys** 获取对象中的所有属性(键),返回数组
+- **Object.keys** 获取对象中的所有属性值(值),返回数组
+- **Object.assign** 常用于对象拷贝
+
+```
+const o = {uname: 'pink',age: 18}
+log(Object.keys(o)) // [uname,age]
+log(Object.values(o)) // ['pink',18]
+// 拷贝
+const oo = {}
+Object.assign(oo,o) // 将 o 对象拷贝给 oo 对象
+// 给对象追加属性
+Object.assign(o,{sex: '男'})
+log(o) // [uname: 'pink',age: 18,sex: '男']
+```
+
+**Array**
+
+Array 是内置构造函数,用于创建数组
+
+常用实例方法:
+
+| 方法 | 作用 | 说明 |
+| ----------- | -------- | ---------------------------------------------------- |
+| **forEach** | 遍历数组 | 不返回数组,经常用于==查找遍历数组元素== |
+| **filter** | 过滤数组 | ==返回新数组==,返回==筛选满足条件==的数组元素 |
+| **map** | 迭代数组 | ==放回新数组==,返回==处理之后==的数组元素 |
+| **reduce** | 累计器 | 返回累计处理的结果,经常用于求和等 |
+| **find** | 查找元素 | 返回符合条件的第一个数组元素值,没则有返回undefined |
+| **every** | 检查数组 | 检查数组中所有元素,都满足某个条件,返回 true或false |
+| **some** | 检查数组 | 检查数组中所有元素,有元素满足条件,返回 true或false |
+| **concat** | 合并数组 | 合并两个数组,返回一个新数组 |
+| **sort** | 排序数组 | 对原数组单元值进行排序 |
+| **reverse** | 反转数组 | 将数组反转 |
+
+```
+// 数组 reduce 方法
+const arr = [1,5,8]
+//1. 没有初始值
+const total = arr.reduce(function(prev,current){
+ return prev + current //上一次的值 + 当前的值
+})
+log(total) // 14
+//2. 有初始值
+const total = arr.reduce(function(prev,current){
+ return prev + current //上一次的值 + 当前的值
+}.10)
+log(total) // 24
+//3. 箭头函数写法
+const total = arr.reduce((prev,current) => prev + current, 10)
+```
+
+案例:有一个员工数组对象,计算当月支出多少薪资
+
+```
+const arr =[
+ {
+ uname: '张三',
+ salary: 10000
+ }, {
+ uname: '李四',
+ salary: 10000
+ }, {
+ uname: '王五',
+ salary: 10000
+ }
+]
+//一定要有初始值,否则默认第一个对象为初始值
+const total = arr.reduce((prev,current) => prev + current.salary, 0)
+log(total) // 30000
+```
+
+静态方法 **Array.from(数组)** 将伪数组转换为真数组
+
+```
+const lis = document.querySelectorAll('ul li')
+const liArr = Array.from(lis)
+```
+
+**String**
+
+常见实例方法1:
+
+| 方法 | 说明 |
+| --------------------------------------- | --------------------------------------------- |
+| **split(’分隔符’)** | 将字符串转换为数组,和 join() 相反 |
+| **substring(起始索引,结束索引)** | 截取字符串 |
+| **startswith(检查字符串,检测开始索引)** | 检测是否以某字符开头,返回布尔值,endwith相反 |
+| **includes(搜索的字符串,位置索引)** | 判断一个字符串是否包含某个字符 |
+
+**Number** **toFixed()** 设置保留小数位的长度
+
+```
+const num = 10.923
+log(num.toFixed(1)) //10.9
+log(num.toFixed(2)) //10.92
+log(num.toFixed()) //11 四舍五入
+```
+
+### 作业
+
+```
+
+
+
+```
\ No newline at end of file
diff --git "a/05 \350\260\242\351\223\226\346\265\251/20231211 \345\233\276\344\271\246\347\256\241\347\220\206 .md" "b/05 \350\260\242\351\223\226\346\265\251/20231211 \345\233\276\344\271\246\347\256\241\347\220\206 .md"
new file mode 100644
index 0000000..295bb51
--- /dev/null
+++ "b/05 \350\260\242\351\223\226\346\265\251/20231211 \345\233\276\344\271\246\347\256\241\347\220\206 .md"
@@ -0,0 +1,140 @@
+```
+/**
+ * 目标1:渲染图书列表
+ * 1.1 获取数据
+ * 1.2 渲染数据
+ */
+const tbody = document.querySelector('.list');
+// 通用的外号
+const creator = '大帅哥';
+// 封装一个先获取数据,再渲染数据的函数
+function render() {
+ axios({
+ url: 'https://hmajax.itheima.net/api/books',
+ params: {
+ creator: creator
+ }
+ }).then(result => {
+ // console.log(result);
+ const bookList = result.data.data;
+ const trHtml = bookList.map((item, i) => {
+ const { id, author, bookname, publisher } = item
+ return `
+
+ | ${i + 1} |
+ ${bookname} |
+ ${author} |
+ ${publisher} |
+
+ 删除
+ 编辑
+ |
+
+ `
+ }).join('')
+ // console.log(trHtml);
+ tbody.innerHTML = trHtml;
+ })
+}
+// 打开网页就得先调用一次函数
+render();
+// 实现添加事件
+const form = document.querySelector('.add-form');
+// 为了控制添加的弹窗,先获取
+const addModalBox = document.querySelector('.add-modal');
+const addModal = new bootstrap.Modal(addModalBox);
+// 给保存添加点击事件
+const add = document.querySelector('.add-btn')
+add.addEventListener('click', () => {
+ // 采集数据
+ const book = serialize(form, { hash: true, empty: true })
+ console.log(book);
+ // 将数据用axios调用接口,提交给服务器
+ axios({
+ url: 'https://hmajax.itheima.net/api/books',
+ method: 'post',
+ data: {
+ creator,
+ ...book
+ }
+ }).then(result => {
+ // console.log(result);
+ // 清空表单
+ form.reset();
+ // 关闭弹窗
+ addModal.hide();
+ // 重新获取列表并渲染
+ render();
+ })
+
+})
+
+// 删除事件
+tbody.addEventListener('click', (e) => {
+ // console.log(e.target);
+ if (e.target.classList.contains('del')) {
+ console.log('删除');
+ // 获取删除id
+ // console.log(e.target.parentNode.dataset.id);
+ const id = e.target.parentNode.dataset.id
+ axios({
+ url: `https://hmajax.itheima.net/api/books/${id}`,
+ method: 'delete',
+
+ }).then(result => {
+ console.log(result)
+ // 重新渲染
+ render()
+ })
+ }
+})
+
+// 编辑图书功能
+tbody.addEventListener('click', (e) => {
+ if (e.target.className === 'edit') {
+ // console.log('修改');
+ // 创建一个弹窗的对象
+ const form = document.querySelector('.edit-form')
+ // 获取弹窗
+ const edit = document.querySelector('.edit-modal')
+ const editModal = new bootstrap.Modal(edit)
+ editModal.show()
+ // 获取id
+ const id = e.target.parentNode.dataset.id;
+ // 通过id调用接口 查询对应的图书数据
+ axios({
+ url: 'https://hmajax.itheima.net/api/books/' + id
+ }).then(result => {
+ // console.log(result.data.data);
+ const book = result.data.data;
+ const { id, author, bookname, publisher } = book;
+ // 将图书馆数据显示到表单
+ form.querySelector('.id').value = id;
+ form.querySelector('.bookname').value = bookname;
+ form.querySelector('.author').value = author;
+ form.querySelector('.publisher').value = publisher;
+ })
+
+ // 修改按钮
+ const editbtn = document.querySelector('.edit-btn');
+ editbtn.addEventListener('click', () => {
+ // 采集数据
+ const book = serialize(form, { hash: true, empty: true })
+ console.log(book);
+ // 提交接口
+ axios({
+ url: 'https://hmajax.itheima.net/api/books/' + id,
+ method: 'put',
+ data:{
+ creator,
+ ...book
+ }
+ }).then(result => {
+ editModal.hide()
+ render()
+ // console.log(result);
+ })
+ })
+ }
+})
+```
\ No newline at end of file
--
Gitee