JS完整知识体系
ES语法规范【重点】
关键字
- 声明变量的关键字
var
: es6以前声明变量,可以重复声明变量,不会报错。let
: es6新增的关键字,用来取代var,比var的好处有块作用域
const
: 声明常量。
- 声明函数的关键字
function
: 声明函数
- 声明类的关键字
class
: 声明类
运算符
数学运算符
-
+ - * / % ++ -- += -= /= *= == ===
let a = 10; let b = 20; let c = a + b; // 30 + 是求和效果 let d = b - a; // 10 - 是减法效果 let e = a * b; // 200 *乘法 let f = a / b // 0.5 除法 let g = a % b; // 10 取余数 console.log(a++) // 先打印10 再自增1 (先使用 再运算) console.log(a--) // 先打印10 在自减1 (先使用 再运算) console.log(++a) // 先自增1 再打印11 (先运算 再使用) console.log(--a) // 先自减1 再打印9 (先运算 再使用) let h += a; // 相当于 h = h + a; let i -= b; // 相当于 i = i - b; a == b // 两个等号 不是全等 只是比较值 不比较类型 a === b // 全等 值和类型都要相等
逻辑运算符
let a = 10;
let b = 20;
a && b // a是true 且 b也是true
a || b // 如果a是true 直接返回true 如果a不是true 判断,b是true,也返回true, 否则返回false。
!a // 取反
位运算符
- 直接操作的是计算机的二进制
10001 0010 01000
【知道这个东西】
语句
流程控制语句
-
if else if else
if (条件) { /* 满足此条件执行的代码 */ } else if (条件) { /* 满足此条件执行的代码 */ } else { /* 以上条件都不满足 执行的代码 */ }
-
switch case
switch (形参) { case 1: /* 形参=1 执行的代码 */ break; case 2: /* 形参=2 执行的代码 */ break; default: /* 以上都不满足 执行这里的代码 */ }
循环语句
-
for 循环
const arr = ['a', 'b', 'c'] // 满足几次 这个循环的代码就会执行几次 for (let i = 0; i < arr.length; i++) { console.log(arr[i]) // arr[i] 代表每一次的值。 这个循环转3圈,每一圈的值。 }
-
while 循环 和 do while 循环
const arr = ['a', 'b', 'c'] // 和for循环差不多 只是写法不同 让我们多一种选择而已 let i = 0; while (i < arr.length) { console.log(arr[i]) i++ } // 和while循环一样 只是先执行一次,再判断。 let i = 0; do { console.log(arr[i]) i++ } while (i < arr.length)
-
for in 循环
# 循环数组 const arr = ['a', 'b', 'c'] for (let index in arr) { console.log(index, arr[index]) } # 注意: 1. 循环数组,index出来是 索引: 0 1 2 2. 取值的话,就是: arr[0] arr[1] arr[2] # 循环对象 const user = { name: '小貂蝉', age: 18, email: 'dc@qq.com' } for (let key in user) { console.log(key, user[key]) } # 注意: 1. 循环对象,key是出来的键名: name, age, email 2. 取值就是: user['name'] user['age'] user['email'] 3. 对象取值,如果key是变量,必须使用 对象[key],不能 user.key
-
for of 循环
const arr = ['a', 'b', 'c'] for (let v of arr) { console.log(v) } # 注意: 1. 循环数组,出来的是: 每一项的值 2. 不能用来循环对象
三目运算
-
语法:
条件 ? 结果1 : 结果2 // 条件是true 走结果1 否则, 走结果2
函数
函数写法
-
【1】声明式函数
function 函数名(形参1, 形参2) { /* 代码块 */ }
-
【2】函数表达式
const 变量 = function (形参1, 形参2) { /* 代码块 */ }
-
【3】箭头函数
const 变量 = (形参1, 形参2) => { /* 代码块 */ } # 注意哦 1. 如果形参只有1个,可以省略 () 2. 如果{}只有1句代码,可以省略{},且必须省略return 3. 箭头函数没有 arguments 哦~~ 4. 箭头函数不能 new 哦 5. 箭头函数的 this,指向上一级作用域
形参和实参
-
形参
:占位使用,叫啥都没有关系,注意语义化 -
实参
:调用函数的时候,传递的参数const 函数名 = (形参1, 形参2) => { /* 代码块 */ } // 调用函数 函数名(实参1, 实参2)
返回值
const 函数名 = (形参1, 形参2) => {
/* 代码块 */
return 结果
}
# 注意
1. 如果函数中不写return,默认return undefined
2. 函数返回啥,就得到啥
3. 在哪里调用函数,返回的结果就返回到哪里。
4. 有返回值的函数,可以使用变量,来接收这个返回值。
函数的调用
const 函数名 = function (形参1, 形参2) {
/* 代码块 */
return 结果
}
const user = {
属性名: 函数名
}
btn.addEventListener('click', function () {})
# 调用方式【6种】
1. 直接调用: 函数名()
2. 对象属性方法调用: user.属性名()
3. 回调函数: 等到一定的时机 再调用
4. IIFE: 自己调用自己
5. call() 和 apply() 调用:
函数名.call(this目标,实参1,实参2) 函数名.apply(this目标,[实参1,实参2])
6. 使用new调用: new 函数名(实参1, 实参2)
内置对象
Array
-
概念: 数组
const arr = ['a', 'b', 'c'] // 取值 arr[索引] // 设置值 arr[索引] = 新的值
-
属性
- length : 获取数组的长度
-
方法:
方法名称 说明 concat 连接两个或多个数组,作用:连接数组,合并数组 reverse 反转数组的顺序, 作用: 反转 push 在数组后面添加元素, 作用: 添加元素 pop 删除数组最后一个元素, 作用:删除元素 unshift 前面加一个元素, 作用:添加元素 shift 前面删除一个元素, 作用: 删除元素 join 数组转字符串, 作用:转字符串 indeOf 查找元素所在的位置, 作用: 找元素索引 includes 看是否包含指定元素, 作用: 找元素 flat 降维 作用:多维数组,变为1维数组 findIndex 作用:找索引 find 作用:找元素 slice 作用: 切割数组,截取元素 sort 作用:排序 splice 作用:添加、删除、修改 元素 forEach 作用:循环,没有返回值 map 作用: 循环, 把每次的结果,放入一个新数组,最后返回这个新数组 filter 作用: 过滤,把每一次满足条件的元素,放入一个新数组,返回这个新数组 every 作用: 每一个都满足,就返回true,否则,返回false some 作用: 只要1个满足,就返回true,否则返回false
String
方法名称 | 作用 |
---|---|
charAt | 根据索引,查找字符 |
charCodeAt | 根据索引,查找字符的编码 |
concat | 连接字符串 |
includes | 查询是否包含 |
indexOf | 查找字符的索引 |
replace | 替换 |
slice | 截取 |
split | 字符串转数组 |
substr | 截取 |
substring | 截取 |
toLowerCase | 转小写 |
toUpperCase | 转大写 |
trim | 取两头空白 |
Date
方法名 | 作用 |
---|---|
getFullYear | 获取年 |
getMonth | 获取月 0 ~ 11 |
getDate | 获取天 0 ~ 31 |
getHours | 获取小时 |
getMinutes | 获取分钟 |
getSeconds | 获取秒 |
getDay | 获取星期 0 ~ 6 |
getTime | 获取 时间戳 |
Math
方法名 | 作用 |
---|---|
Math.PI | 圆周率 3.1415926… |
Math.abs | 绝对值 | -10 | -》 10 |
Math.ceil | 向上取整 |
Math.floor | 向下取整 |
Math.max | 取最大值 |
Math.min | 取最小值 |
Math.random | 取随机数 0 ~ 1 |
Math.round | 四舍五入 |
Number
方法名 | 作用 |
---|---|
toFiexd | 保留小数点位数 |
Object
方法名 | 作用 |
---|---|
keys | 取出所有的key,放入一个数组 |
assign | 合并多个对象 |
JavaScript高级特性【es5】
作用域
- 作用域
- 概念:标识符访问的 “范围”。
- 作用域链: 从里往外,逐级向上查找,找到就使用,找不到就报错
- 作用域分类:
- 全局
- 局部
- 块级
闭包
- 【1】函数跨作用域访问变量,形成闭包,闭包是一种作用域的体现
- 【2】闭包的写法是,父函数嵌套子函数,子函数访问父函数的变量,把子函数返回或挂在全局
- 【3】闭包的作用是:解决循环定时器问题,解决循环事件绑定问题,实现早期的模块化。
- 【4】闭包的优缺点:优点是把变量隐藏在内部,避免全局污染。缺点是:过多使用闭包,变量常驻内存,不会被释放,造成内存开销过大,甚至内存泄漏。
原型
概念:
- 【1】每个函数都有一个属性
prototype
,就是原型【显示原型】 - 【2】添加在原型上的属性和方法,被所有实例对象共享
- 【3】实例对象都有一个属性
__proto__
,指向构造函数的prototype
- 【4】原型
prototype
上有一个属性constructor
, 指向构造函数本身。
作用:添加共享方法
原型链
- 【1】原型
prototype
本身也是实例对象,也有__proto__
, 指向Object的prototype
- 【2】
Object.prototype
也是实例对象,也有__proto__
, 指向null
- 【3】
Object.prototype
也有属性constructor
,指向构造函数本身。
作用: 添加共享方法
this
-
7种指向
- 全局 -》 window
- 函数 -》 调用者
- 对象方法 -》 调用者
- 构造函数 -》 实例对象
- 事件绑定 -》 事件源
- 定时器 -》 window
- 箭头函数 -》上一级
-
改变指向方法
-
call()
函数.call(this的指向目标, 参数1, 参数2)
-
apply()
函数.apply(this的指向目标, [参数1, 参数2])
-
bind()
let 新函数 = 函数.bind(this的指向目标) # 注意 1. 当我们调用新函数,新函数中的this,就永远指向之前绑定的 目标
-
类型检测
-
typeof检测基本类型
typeof 'abc' // string typeof true // boolean typeof 10 // number typeof undefined // undefined typeof function () {} // function typeof Symbol() // symbol typeof null // object typeof {} // object typeof [] // object
-
instanceof检测引用类型
[] instanceof Array // true {} instanceof Object // true new Date() instanceof Date // true
-
Object.prototype.toString.call() 检测所有类型
Object.prototype.toString.call('abc') // [Object String] Object.prototype.toString.call(10) // [Object Number] Object.prototype.toString.call(true) // [Object Boolean] Object.prototype.toString.call(undefined) // [Object Undefined] Object.prototype.toString.call(null) // [Object Null] Object.prototype.toString.call(Symbol()) // [Object Symbol] Object.prototype.toString.call(function () {}) // [Object Function] Object.prototype.toString.call([]) // [Object Array] Object.prototype.toString.call({}) // [Object Object]
-
Array.isArray() 检测是否是数组
深拷贝&浅拷贝
-
浅拷贝
-
for in循环
let 对象1 = { 属性名:属性值 ... } let 对象2 = {} for (let key in 对象1) { 对象2[key] = 对象1[key] }
-
Object.assign
let 对象1 = { 属性名:属性值 ... } let 对象2 = Object.assign({}, 对象1)
-
扩展运算符
let 对象1 = { 属性名:属性值 ... } let 对象2 = { ...对象1 }
-
-
深拷贝
-
JSON.stirngify()
-
JSON.parse()
let 对象1 = { 属性名:属性值 属性名: { key:value } } let 对象2 = JSON.parse( JSON.stringify(对象1) )
-
ES6
解构
# 解构对象
const {变量1, 变量2} = 对象
# 解构数组
const [变量1, 变量2] = 数组
# 解构函数参数
function 函数名({变量1, 变量2}) {}
function 函数名([变量1, 变量2]) {}
扩展运算符
# 展开字符串
...字符串
# 展开数组
...数组
# 合并数字
[...数组1, ...数组2]
# 浅拷贝数组
const 新数组 = [...要拷贝的数组]
# 浅拷贝对象
const 新对象 = {...要拷贝的对象}
# 合并对象
const 新对象 = {...对象1,...对象2}
# rest参数
function 函数名(形参1,...rest) {}
# 伪数组变为真数组
const 真数组 = [...伪数组]
模板字符串
# 语法
`${表达式}`
# 注意:
1. 表达式:有唯一返回值。
对象的简洁写法
const 对象 = {
name, // key和value相同,省略
属性名() {} // 方法省略 :function
}
class
# 类的写法
class 类名 {
// 相当于在构造函数中写: this.属性名 = 属性值
属性名=属性值
// 构造函数
constructor() {}
// 原型方法
方法名() {}
// 静态方法
static 方法名() {}
}
# 继承
class A {}
class B extends A {
constructor() {
super()
this.属性名=属性值
}
}
模块化语法
# 方式一
export 要导出的东西
import {xx, yy} from '路径或模块名'
# 方式二
export default {} // 注意: 1个js文件中,只能写1次
import 变量 from '路径或模块名'
Promise
-
基本语法
new Promise((resolve, reject) => { if (成功) { resolve('一些成功数据') // 传递给下一个then } else { reject('一些失败数据') // 传递给下一个catch } }).then((data) => { // data就是上一步resolve()里面的数据 }).catch((err) => { // err就是上一步 reject()里面的数据 })
-
解决回调地狱【回调的代码,编成从上往下扁平的代码】
# 回调地狱 axios.get(url1).then((res) => { axios.get(url2).then((res) => { axios.get(url3).then((res) => { }) }) }) # Promise解决代码 new Promise((resolve) => { axios.get(url1).then((res) => { resolve(res.data) }) }).then((data) => { return new Promise((resolve) => { axios.get(url2).then((res) => { resolve(res.data) }) }) }).then((data) => { return new Promise((resolve) => { axios.get(url3).then((res) => { resolve(res.data) }) }) }).then((data) => { console.log(data) })
Async和Await
概念:
-
async
: 声明函数中有异步代码 -
await: 等待Promise结果
async function 函数名() { let 右侧resolve的结果 = await Promise的函数调用 }
-
解决回调地狱
# 回调地狱 axios.get(url1).then((res) => { axios.get(url2).then((res) => { axios.get(url3).then((res) => { }) }) }) # async和await解决回调地狱 async function getData() { let 结果1 = await axios.get(url1) let 结果2 = await axios.get(url2) let 结果3 = await axios.get(url3) } getData()
BOM【掌握】
概念:
学习它的属性和方法,可以操作浏览器。
location
作用: 操作浏览器的 地址栏
# 属性 http://www.baidu.com:443/img/logo.png?user=admin&id=666#pid=555
href // 完整地址 location.href="" 进行跳转
origin // 协议 + 域名 + 端口 http://www.baidu.com:443
host // 域名 + 端口 www.baidu.com:443
hostname // 域名 www.baidu.com
port // 端口 443
pathname // 路径 /img/logo.png
search // 参数 ?user=admin&id=666
hash // #pid=555
protocol // 协议 http
history
作用:操作地址栏的历史记录
# 操作历史记录
history.go() // 跳转
history.back() // 向后
history.forward() // 向前
navigator
作用: 获取浏览器的一些信息,判断用户使用啥浏览器,使用啥语言,判断用户的浏览器的 环境。
# 获取浏览器信息
navigator.userAgent // 获取用户代理信息
navigator.language // 获取语言
screen
作用: 获取屏幕信息
# 获取屏幕信息
width // 宽度
height // 高度
window
# 浏览器窗口对象
window.alert() // 弹窗
window.setTimeout() // 定时器
window.onscroll = function () {} // 滚动条滚动
window.onresize = function () {} // 窗口大小发生变化
window.confirm() // 弹出确认框
window.onload = function (){} // 页面加载完毕
window.open() // 打开某个网址
DOM【理解】
概念:
操作节点,可以获取节点,修改节点,新增节点,删除节点,改变节点的属性(修改css,变化效果)。
操作节点
获取节点
# H5
document.querySelector('选择器')
document.querySelectorAll('选择器')
# H4
document.getElementById()
document.getElementsByName()
document.getElementsByClassName()
document.getElementsByTagName()
删除节点
dom.remove() // 把节点本身删除掉
dom.removeChild() // 把节点的儿子删除
dom.innerHTML = "" // 清空节点
dom.innerText = "" // 清空节点内容
dom.textContent = "" // 清空节点内容
修改节点
dom.innerHTML = '新的内容'
dom.innerText = "新的内容"
dom.textContent = "新的内容"
添加节点
const 节点 = document.createElement('节点标签名')
dom.appendChild(节点)
操作样式
直接操作style
dom.style.css属性名 = '新的值'
操作类名
dom.className = "新的类名"
操作属性
H4操作属性
# 标准属性
dom.属性名 // 获取 dom.id
dom.属性名 = '新的属性值' // 修改 dom.id = 'box'
# 自定义属性
dom.getAttribute('属性名') // 获取自定义属性的值
dom.setAttribute('属性名', '新的属性值') // 修改自定义属性的值
H5操作属性
# 自定义属性
dom.dataset.属性名 // 获取
dom.dataset.属性名 = '新的值' // 设置
Dom事件
绑定事件
dom.addEventListener(事件类型, function () {
/* 事件处理函数 */
})
事件类型
dom.addEventListener(事件类型, function () {
/* 事件处理函数 */
})
# 事件类型
click // 点击
dblclick // 双击
focus // 聚焦
keydown // 键盘按下
keypress // 某个键盘的键被按下或按住
keyup // 某个键盘的键被松开
mousedown // 某个鼠标按键被按下
mouseup // 某个鼠标按键被松开
mousemove // 鼠标被移动
mouseout // 鼠标从某元素移开
mouseover // 鼠标被移到某元素之上
change // 输入框的值发生变化
submit // 提交
input // 输入
事件源
dom.addEventListener(事件类型, function (e) {
/* 事件处理函数 */
e就是事件对象 里面有一些有用的信息
e.target 事件源
e.preventDefault() // 阻止默认行文
e.stopPropagation() // 阻止冒泡
})
事件委托
- 事件委托(事件委派、事件代理)
- 概念: 给子绑定的事件,绑定在父上面
- 作用:
- 性能好。
- 如果子元素是动态添加的,帮不上事件的哦。需要绑定在父上面。
Ajax【重点】
作用:
我们前端写页面,很多数据都是写死的,需要和后端(java工程师),进行数据交互。
原生aJax【了解】
get方式【4步】
// 1. 创建ajax对象
const xhr = new XMLHttpRequest()
// 2. 配置方式和地址
xhr.open('get', url?参数名=参数值)
// 3. 发送请求
xhr.send()
// 4. 监听状态变化 接收数据
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
var data = xhr.responseText;
}
}
post方式【5步】
// 1. 创建ajax对象
const xhr = new XMLHttpRequest()
// 2. 配置方式和地址
xhr.open('post', url)
// 3. 设置请求头
xhr.setRequestHeader('Content-Type', 'applciation/x-www-form-urlencode')
// 4. 发送请求
xhr.send('参数名=参数值')
// 5. 监听状态变化 接收数据
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
var data = xhr.responseText;
}
}
axios【重点】
get方式
# 方式一
axios.get(url?参数名=参数值).then(res => {
// res.data就是数据
}).catch(err => {
// err是错误信息
})
# 方式二
axios.get(url, {
parmas: {
参数名:参数值
}
}).then(res => {
// res.data就是数据
}).catch(err => {
// err是错误信息
})
post方式
axios.get(url, {
参数名:参数值
}).then(res => {
// res.data就是数据
}).catch(err => {
// err是错误信息
})
get和post的区别
- get参数在地址栏,游览器有限制地址栏长度,所以不能传递太多参数,post可以。
- get参数在地址栏,post参数在请求体
- get不安全,参数暴露在地址来,post相对安全。
- get不需要设置请求头(有些时候也需要),post需要设置。
解决问题的方式和方法
JS 【5法】
- 打印法 【JS每一步都可以打印】
- 注释(删除)法 【快速找到错误代码】
- 断点法debugger 【调试看结果】
- 找茬法 【仔细对比每一个标点符号】
- 翻译法 【把错误翻译 解决了80%】
Ajax 【4看 + 2看】
-
地址
-
方式和状态码
-
参数
-
响应
-
请求头
-
响应头
CSS问题【3查】
-
【1】没选中 【如果审查元素 看不到自己写 那就是没有选中】
-
【2】权重不够 【如果审查元素 看到自己的 被一根 横线 ---- 划掉了,就是权重不够】
-
【3】审查元素,看到元素前面有黄色倒三角感叹号,就是属性写错了。