一. 变量的声明
(一) 变量var
- 可以重复声明, 后面的声明会覆盖前面的
- 没有块作用域 (ES5 只有函数作用域, 没有块作用域)
(二)变量let
- Es6新增了let命令,不能重复声明, 有块级作用域
(三)常量const
- 必须要给初始值
- 定义常量, 不能重复声明
- 如果const 定义的是数组和对象,那么修改其中的内容,是可以的
二. 嵌套循环
- 循环中再写循环就叫循环嵌套
let arr = [
{name: "小貂蝉", hobs: ["html", "css", "js"]},
{name: "阳仔", hobs: ["捏脚", "spa", "LOL"]},
{name: "张三", hobs: ["捏脚", "瑜伽", "LOL"]}
]
// 目的:取出每一个人的爱好,并打印在控制台上
// 1.先取第一层的元素
for (let i = 0; i < arr.length; i++) {
// 2.第一层的元素是对象,取hobs,arr[i].hobs
// console.log(arr[i]);
// 3.hobs是一个数组,再用for循环去hobs中的每一个元素
// console.log(arr[i].hobs)
for(let j = 0; j < arr[i].hobs.length; j++) {
// 4.取出每一个人的爱好,并打印在控制台上
console.log( arr[i].name, arr[i].hobs[j]);
}
}
三. 函数专题
(一)函数的写法
- 声明式
//ES5
function getSum(){}
function (){}//匿名函数
//ES6
()=>{}
//如果{}内容只有一行 那{}和return关键字可省,
- 表达式
//ES5
var sum=function(){}
//ES6
let sum=()=>{}//如果{}内容只有一行{}和return关键字可省,
- 构造函数
const sum = new Function('a', 'b' , 'return a + b')
(二)函数的作用
- 复用封函数,变化设参数
- 如果需要实现一个功能,而且这个功能的代码函数超过5行,功能到处用,就可以封装函数了
// 写一个函数,计算身高体重的健康指数(BMI):
// 计算公式为:BMI=体重(千克)除以身高(米)的平方。
// 声明这个参数
function calcBMI(weight, height) {
// 函数体的逻辑
return weight / (height * height) ;
}
// 直接去使用函数
console.log(calcBMI(45, 1.6))
(三)函数的参数
- 形参:定义函数时的参数,取啥名都可以,最好还是语义化
- 实参:调用函数时,实际传入的参数 ,实参和形参是一一对应的
- 默认参数:
// ES5 写法: 默认参数的写法
function fn(num) {
let temp = num || 0;
}
// ES6默认参数的写法
function fn(num = 0) {}
- arguments: 伪数组:具有length属性;可以使用for循环。
// 实现一个不定参数的求和的函数;
function sum() {
// 1.获取所有的参数
console.log(arguments)
let res = 0;
// 2.直接对arguments里面的所有元素进行求和
for(let i = 0; i < arguments.length; i++) {
res += arguments[i];
}
return res;
}
// 3.函数的使用
let resSum = sum(1, 2 ,3 ,4);
console.log(resSum);
(四)函数的返回值
- 哪里调用该函数,返回值就返回到哪里(调哪返哪)
- 没有return,函数的返回值是undefined
四. 数组的API
- 不影响原数组的api
1.concat 连接数组
let arr1 = ["hello"];
let arr2 = ["秀儿"];
let res = arr1.concat(arr2);
2.join :可以将数组转化为字符串
let res = arr1.join(分隔符)
3.indexOf:如果参数不是数组的中的元素,返回值-1;若是,从数组的第0项开始匹配,匹配到了,则返回下标值
let index = arr1.indexOf(某一项元素)
4.lastIndexOf: 和indexOf匹配的方向相反,匹配到了,则返回下标值。如果参数不是数组的中的元素,返回值-1
let index = arr1.lastIndexOf(某一项元素)
5.slice: 从已有的数组中返回选定的元素
let resArr = array.slice(start, end)
6.includes: 用来判断一个数组是否包含一个指定的值,如果是返回 true,否则false
let flag = arr.includes(某一项元素)
7.flat: 嵌套数组转一维数组
let newArray = arr.flat(depth)
- 影响原数组的api 1.reverse: 反转数组
let newArr = arr1.reverse();
2.splice:方法用于添加或删除数组中的元素
let newArray = arr1.splice(index,howmany,item1,.....,itemX)
// 删除元素
let arr = ["html", "css", "js"];
let resArr = arr.splice(1, 1)
console.log("原数组:", arr);
console.log("返回值:", resArr);
// 可以从任意位置对数组进行删除和增加
let resArr = arr.splice(1, 1, 2, 3);
console.log("原数组:", arr);
console.log("返回值:", resArr);
3.push: 向数组末尾添加一个或多个元素
let res = arr.push(元素)
# 也可添加多个元素
let res = arr.push(元素1, 元素2, ...)
4.pop: 把数组末尾元素删除
let res = arr.pop()
5.shift:删除并返回数组的第一个元素
let res = arr.shift();
6.unshift: 向数组的开头添加一个或多个元素,并返回新的长度
let resL = arr.unshift(元素)
# 也可添加多个元素
let res = arr.unshift(元素1, 元素2, ...)
- sort: 方法用于对数组的元素进行排序
let res = array.sort(function(a, b) {
// return a - b // 升序
// return b - a // 降序
})
五. 遍历数组
1.forEach:遍历数组
arr.forEach(function(val, index) {
// 处理逻辑
})
2.map:使用返回值的,遍历数组的一个方法
// map会创建一个新的空数组,将原数组遍历之后,对每个元素进行操作,返回到新数组中
let newArray = arr.map(function(val, index) {
// 处理逻辑
return xxx
})
3.filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素
let newArray = arr.filter(function(val, index) {
return 过滤条件
})
4.every() 方法用于检测数组所有元素是否都符合指定条件,符合是true,否则false
let res = arr.every(function(val, index) {
return 符合条件
})
5.some() 方法用于检测数组中的元素是否满足指定条件
let res = arr.some(function(val, index) {
return 符合条件
})
6.find() 方法返回通过测试(函数内判断)的数组的第一个元素的值
let res = arr.find(function(val, index) {
return 符合条件
})
7.findIndex() 方法返回传入一个测试条件(函数)符合条件的数组第一个元素位置
let res = arr.findIndex(function(val, index) {
return 符合条件
})
六. Object的两个方法
1.Object.assign()---合并
# 要用于将一个或多个源对象复制到目标对象,它将返回目标对象。
# 参数中的目标对象通常用{}
let targetObj = Object.assign(目标对象,源对象1,源对象2, 源对象3, ...)
注意:合并时,如果存在相同的key,则后面的会覆盖前面的
1.Object.keys()---合并
# Object.keys() 方法会返回一个由一个给定对象的自身可枚举属性组成的数组。
let keysArr = Object.keys(obj);
// 常见用法: 使用Object.keys()遍历对象
Object.keys(obj2).forEach(function(val, index) {
console.log(val, obj2[val])
})
七. Date对象
// 目的:给日期补0
function getCurrentTime() {
let date = new Date();
// 1.先获取年月日
// 用来获取年限
let Y = date.getFullYear();
// 从 Date 对象返回月份 (0 ~ 11)
let M = date.getMonth() + 1;
// 用来获取日期的
let D = date.getDate();
// return [Y, M, D].map(function(val) {
// return val > 10 ? val : "0" + val;
// }).join("/");
// newArr [2022, "07", "05"]
let newArr = [Y, M, D].map(function(val) {
return val > 10 ? val : "0" + val;
});
// newStr "2022/07/05"
let newStr = newArr.join("/")
return newStr;
}
console.log(getCurrentTime());
八. 正则表达式
1. 正则表达式js提供的一套规则,用来处理字符串的,具有强大的字符串处理能力
2. 正则表达式的写法
const reg = new RegExp("表达式", "修饰符") // 修饰符是可选的
示例:
new RegExp("abc", "i"); // i代表不区分大小写
const reg = /表达式/修饰符;
// 检测字符串是否符合正则表达式的规则,若符合,则返回true,否则返回false
正则.test(字符串)
3. 正则表达式的示例
// 验证手机号
# 1.要以1开头。 2.位数11位。 3. 13 14... 19开头的手机号
# [12345] [1-5]:只匹配一个 [1-5]{10} {2, 10}
const reg = /^1[3-9][0-9]{9}$/;
reg.test("13522223333");
// 验证邮箱
# 邮箱:xxx@qq.com xxx@163.com xxx@itsource.cn com|cn|org|cc
const reg = /^[a-zA-Z0-9]+@[a-zA-Z0-9]+\.(com|cn|org|cc)$/
reg.test("邮箱号")
九. 注册表单验证
// 1.获取dom
let userNameIpt = document.querySelector("#userNameIpt");
let emailIpt = document.querySelector("#emailIpt");
let passwordIpt = document.querySelector("#passwordIpt")
let regBtn = document.querySelector(".reg-btn");
let tips = document.querySelectorAll(".tips");
// 增加标识
let usernameFlag = false;
let emailFlag = false;
let passwordFlag = false;
function checkUsername() {
// 获取用户输入的用户名
let username = userNameIpt.value;
// 用户名的正则表达式 中文、字母、数字、下划线 长度2~12位
const userNameReg = /^[\u4E00-\u9FA5a-zA-Z0-9_]{2,12}$/;
if (userNameReg.test(username)) {
// console.log("你输对了")
tips[0].style.color = "#ccc";
usernameFlag = true;
} else {
// 输错之后的提示:提示变红
tips[0].style.color = "red"
usernameFlag = false;
}
}
// 失焦事件监听
userNameIpt.addEventListener("blur", checkUsername);
function checkEmail() {
let email = emailIpt.value;
// 邮箱的正则表达式:有效的邮箱
const emailReg = /^[a-zA-Z0-9]+@[a-zA-Z0-9]+\.[a-zA-Z]+$/;
if (emailReg.test(email)) {
tips[1].style.color = "#ccc";
emailFlag = true;
} else {
tips[1].style.color = "red";
emailFlag = false;
}
}
emailIpt.addEventListener("blur", checkEmail)
function checkPassword() {
let password = passwordIpt.value;
// 密码的正则表达式:字母、数字、下划线长度6~12位
const passwordReg = /^[a-zA-Z0-9_]{6,12}$/;
if (passwordReg.test(password)) {
tips[2].style.color = "#ccc";
passwordFlag = true;
} else {
tips[2].style.color = "red"
passwordFlag = false;
}
}
passwordIpt.addEventListener("blur", checkPassword)
regBtn.addEventListener("click", function () {
if (usernameFlag && emailFlag && passwordFlag) {
console.log("全部验证通过,可以注册了")
} else {
console.log("验证不通过,请检查")
}
})
十. 事件对象
1.事件对象: 触发事件时,事件对象会作为默认参数默认传入到function中
2.事件对象的属性
- e.target: 事件源
- e.type: 事件类型
- e.clientX: 水平坐标
- e.clientY: 垂直坐标
- e.keyCode: 键盘码
- e.which: 鼠标按键的值
3.事件对象的方法
- e.preventDefault() ---阻止浏览器的默认行为 / 阻止a标签的跳转
- e.stopPropagation() ---阻止事件冒泡
4.事件委派
- 事件委派,就是嵌套内部的标签需要触发的事件,不直接绑到嵌套内部的标签,而是把事件绑定到父标签上
- 事件委派的好处:提高性能; 动态渲染的标签也可以触发事件
<!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>
</head>
<body>
<ul id="list">
<li>111</li>
<li>222</li>
<!-- ---- -->
</ul>
<script>
setTimeout(function () {
// 创建一个li标签
let li = document.createElement("li");
// 添加内容
li.textContent = "我是新来的";
// 加入ul中
list.appendChild(li);
// console.log("9999");
}, 3000);
// 获取ul
const list = document.querySelector("#list");
// 获取所有li
// const lis = document.querySelectorAll("li");
// // 循环绑定事件
// lis.forEach(function (li) {
// li.addEventListener("click", function () {
// console.log("666");
// });
// });
// 事件委托(事件委派 / 事件代理): 本来是给儿子绑定的事件 委托给了父亲绑定
list.addEventListener("click", function () {
console.log("5555");
});
</script>
</body>
</html>
十一. Ajax
1.介绍
- Ajax是一种前端和服务端交互的技术,从服务端获取的数据可以动态的渲染到页面上。页面是局部刷新的
2.原生Ajax发送get请求
// 1.创建Ajax对象
let xhr = new XMLHttpRequest();
// 2.配置请求方法和请求地址 (后端给的 参数的确定也是后端的)
xhr.open("get", "url?参数名1=参数值1&参数名2=参数值2");
// 3.发送请求
xhr.send();
// 4.监听Ajax对象的状态,在合适的时候,接收数据
xhr.onreadystatechange = function () {
// readyState Ajax对象的状态码 status http请求的状态码
if (xhr.readyState === 4 && xhr.status === 200) {
let data = JSON.parse(xhr.responseText); // 字符串转为对象
console.log(data);
}
};
3.原生Ajax发送post请求
// 1.创建Ajax对象
let xhr = new XMLHttpRequest();
// 2.配置请求方法和请求地址 (后端给的)
xhr.open("post", "url");
// 3. 设置请求头 ( 设置参数的格式 )
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
// 4. 发送Ajax请求
xhr.send('参数名1=参数值1&参数名2=参数值2')
---------------------------------------------
// 3. 设置请求头 ( 设置参数的格式 )
xhr.setRequestHeader('Content-Type', 'application/json')
// 4. 发送Ajax请求
xhr.send(JSON.stringify({name: '参数值'}))
// 5.监听Ajax对象的状态,在合适的时候,接收数据
xhr.onreadystatechange = function () {
// readyState Ajax对象的状态码 status http请求的状态码
if ( xhr.readyState === 4 && xhr.status === 200) {
let data = JSON.parse(xhr.responseText); // 字符串转为对象
console.log(data)
}
};
4.Ajax对象的状态码
- 0 请求未初始化
- 1 服务器连接已建立,但是请求还没接收
- 2 请求已接收
- 3 请求处理中,如果数据量过大,数据没有全部发送。
- 4 **请求已完成,且响应已就绪**
5.http请求的状态码
- 200 请求已成功
- 301 永久重定向
- 302 临时重定向
- 304 缓存
- 400 请求参数有误
- 403 服务器拒绝你的请求
- 404 请求方式有误或者请求地址不对
- 5xx 服务端(后端)发生错误
6.## Ajax调试
- 1.看地址(后端给的地址)
- 2.看请求方式和请求状态 (请求方式对不对-要看文档,请求状态----绿色表示成功)
- 3.看参数
- 4.看响应值
十二. axios
1.介绍
- axios是基于原生Ajax封装的一个用于前后端交互的库
2.引入axios
// 1.在线获取
<script src="https://cdn.bootcdn.net/ajax/libs/axios/1.0.0-alpha.1/axios.js"></script>
// 1.bootcdn搜索 https://www.bootcdn.cn/
// 2. https://cdn.bootcdn.net/ajax/libs/axios/1.0.0-alpha.1/axios.js
// 3.创建本地文件复制该文件。
// 4.本地引入
<script src="./lib/axios.js"></script>
3.发送get请求
axios.get(url?参数名1=参数值1&参数名2=参数值2).then(function(res) {
// response 请求接口之后的响应值 需要的数据 res.data
console.log(res.data)
})
axios.get(url, {
params: {
参数名1: 参数值1,
参数名2: 参数值2,
参数名3: 参数值3,
...
}
}).then(function(res) {
// response 请求接口之后的响应值 需要的数据 res.data
console.log(res.data)
})
4.发送post请求
axios.post(url, {
参数名1: 参数值1,
参数名2: 参数值2,
参数名3: 参数值3,
...
}).then(function(res) {
// response 请求接口之后的响应值 需要的数据 res.data
console.log(res.data)
})