参考:
VsCode插件
JS基础 JS执行机制 JS是一门单线程语言,通过异步和同步可以实现类似多线程操作。同步任务 都在主线程上执行,形成一个执行栈 ;异步通过回调函数实现,异步任务 会添加到任务队列(消息队列),等待同步任务都执行完毕后任务队列中的任务按照异步API 规定的顺序进入执行栈执行,首个异步任务执行完后会回到任务队列查询剩余异步任务,如存在则再次进入执行栈执行,循环往复(事件循环 ),直到任务全部执行完毕
Promise() new 出来的实例对象代表一个异步操作
模板字符串 1 2 3 4 document .write ('大家好,我叫' + name + ',今年' + age + '岁' )document .write (`大家好,我叫${name} ,今年${age} 岁` )
数据类型转换 隐式转换(数字相加 字符相连):
如果+
号左右只有一个值,解析的结果是正号,可用于隐式转换;如果两边都是数值(Number)类型 则是+
号运算符;+
号的左右如果有一个数据是字符串数据类型的话 那么这个+
号会被解析成连接符
除了+
以外的算术运算符 比如 -
*
/
++
--
等都会把数据转成数字类型
显式转换:
Number(数据)
转成数字类型
parseInt(数据)
只保留整数
parseFloat(数据)
可以保留小数,可过提取以数字开头的非数字结尾的数字
String(数据)
转换为字符型
变量.toString(进制)
转换为字符型(可进制转换)
三元运算符(表达式) if条件语句双分支简化写法,一般用来取值,返回值为满足条件内的值
1 条件 ? 满足条件执行的代码 : 不满足条件执行的代码
字符串属性和方法 length 获取字符串长度
split() 转化为数组
1 2 3 const str = 'one,two' console .log (str.split (',' ))
substring() 字符串截取
1 2 3 const str = 'one,two' console .log (str.substring (4 )) console .log (str.substring (0 , 1 ))
startsWith() 判断是否以某字符串开头的
1 2 3 const str = 'one,two' console .log (str.startsWith ('one' )) console .log (str.startsWith ('two' , 4 ))
includes() 判断是否包含某字符串
1 2 3 const str = 'one,two' console .log (str.includes ('two' )) console .log (str.includes ('two' , 6 ))
number toFixed() 让数字指定保留的小数位数
1 2 3 const num = 10.923 console .log (num.toFixed ()) console .log (num.toFixed (2 ))
String() 将数字转化为字符串
函数 基础概念 函数提升 JS会把所有函数声明提升(不提升赋值,所以函数表达式不会被提升)到当前作用域前面,所以可以先调用后声明
动态参数 不设置函数形参,输入的实参全部放入arguments伪数组,遍历获取
1 2 3 4 5 6 7 function getSum ( ) { let sum = 0 for (let i = 0 ; i < arguments .length ; i++) { sum += arguments [i] } } getSum (1 , 2 , 3 )
剩余参数 ...
作为形式参数使用,多余的实参通过...
以数组的形式传入arr
1 2 3 4 5 6 7 const [a, b, ...arr] = [1 , 2 , 3 , 4 ]function fun (a, b, ...arr ) { console .log (arr) } fun (1 , 2 , 3 , 4 )
展开运算符 ...
后面接数组,可以展开数组(去除[]
)
1 2 let arr = [1 , 2 , 3 ]console .log (Math .max (...arr))
匿名函数
1 2 let fn = function ( ) {}fn ()
箭头函数 多用于简化匿名函数表达式,无动态参数,有剩余参数,没有自己的this,沿用上层作用域的this
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 const fn = function ( ) { console .log (123 ) } const fn = ( ) => { console .log (123 ) } const fn = (x ) => { console .log (x) } const fn = x => { console .log (x) } const fn = (x ) => { return x + x } const fn = x => x + xconst fn = uname => ({uname : uname})
立即执行函数 防止变量污染,不需要调用,直接执行,多个立即执行函数必须要用;
分开
1 2 3 4 (function ( ) { console .log ('立即执行函数' ) })(); (function ( ) { console .log ('立即执行函数' ) }());
this 普通函数this
指向函数调用者,箭头函数沿用上层this
改变this
指向
1 2 3 4 5 6 7 8 9 10 11 12 13 14 const obj = { uname : 'pink' } function fn (x, y ) { console .log (this ) console .log (x + y) } fn.call (obj, 1 , 2 ) fn.apply (obj, [1 , 2 ]) const fun = fn.bind (obj, [1 , 2 ])fun ()
回调函数 被当参数的函数
递归函数 自己调用自己的函数
闭包 内层函数调用外层函数变量形成闭包,可以实现数据私有,从外部访问函数内部变量,但可能会造成内存泄漏
1 2 3 4 5 6 7 8 9 10 function count ( ) { let i = 0 function fn ( ) { i++ console .log (`函数被调用了${i} 次` ) } return fn } const fun = count ()
节流 连续触发事件但是在 n 秒中只执行一次函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 const box = document .querySelector ('.box' )let i = 1 function mouseMove ( ) { box.innerHTML = ++i } function throttle (fn, t ) { let startTime = 0 return function ( ) { let now = Date .now () if (now - startTime >= t) { fn () startTime = now } } } box.addEventListener ('mousemove' , throttle (mouseMove, 500 )) box.addEventListener ('mousemove' , _.throttle (mouseMove, 500 ))
防抖 在 n 秒内又触发了事件,则会重新计算函数执行时间
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 const box = document .querySelector ('.box' )let i = 1 function mouseMove ( ) { box.innerHTML = ++i } function debounce (fn, t ) { let timeId return function ( ) { if (timeId) clearTimeout (timeId) timeId = setTimeout (function ( ) { fn () }, t) } } box.addEventListener ('mousemove' , debounce (mouseMove, 200 )) box.addEventListener ('mousemove' , _.debounce (mouseMove, 200 ))
杂项 1 2 document .oncontextmenu = document .ondragstart = document .onselectstart = function ( ) { return !1 }
数组 操作数组 增
1 2 3 4 arr.push (元素1 , 元素2 , ...) arr.unshift (元素1 , 元素2 , ...)
删
1 2 3 4 5 6 7 arr.pop () arr.shift () arr.splice (起始位置, 删除几个元素) arr.splice (0 , 3 )
拷贝
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 const arr = [ 1 , 2 , { name : 'pig' } ]; const newArr = arrconst newArr = [...arr]let newArr = []newArr = newArr.concat (arr)
遍历 forEach()
无返回值
1 arr.forEach (function (item, index ) { })
迭代 map()
返回新数组,常用于处理数据
1 arr.map (function (item, index ) { return item + 20 })
筛选 filter
返回满足条件的数组
1 arr.filter (function (item, index ) { return item >= 20 })
查找 find()
方法返回数组中满足提供的测试函数的第一个元素的值。否则返回 undefined。
1 2 3 4 5 6 7 8 9 10 11 const arr = [ { name : '小米' , price : 1999 }, { name : '华为' , price : 3999 }, ] arr.find (function (item ) { return item.name === '小米' })
累加器 reduce()
1 2 3 4 5 6 arr.reduce (function (累计值, 当前元素 ){}, [起始值]) arr.reduce (function (prev, item ) { return prev + item }, 0 ) const re = arr.reduce ((prev, item ) => prev + item, 0 )
拼接 join()
将数组转化成字符串拼接起来
1 2 3 4 5 6 7 const elements = ['Fire' , 'Air' , 'Water' ];console .log (elements.join ()); console .log (elements.join ('' )); console .log (elements.join ('-' ));
翻转 reverse()
伪数组转为真数组 t通过内置结构函数 Array 的 from()
数组解构 将数组的单元值快速批量赋值给一系列变量
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 const [a, b, c, d] = [1 , 2 , 3 , 4 ]const [a, b, [c, d]] = [1 , 2 , [3 , 4 ]]let a = 1 let b = 2 ; [a, b] = [b, a] const [a = 0 , b = 0 ] = [1 , 2 ]const [a, b, ...arr] = [1 , 2 , 3 , 4 ]const [a, , c, d] = [1 , 2 , 3 , 4 ]
自定义方法 通过原型对象prototype
1 2 3 4 5 let arr = [1 , 2 , 3 ]Array ..max = function ( ) { return Math .max (...this ) } console .log (arr.max ())
对象 创建对象
通过字面量创建
1 2 3 const obj = { name : '佩奇' }
利用 new Object 创建
1 2 3 4 let obj = new Object ()obj.name = '佩奇' let obj = new Object ({ name : '佩奇' })
通过构造函数 批量创建类似对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 function Pig (name, age ) { this .name = name this .age = age } Pig .weight = 200 Pig .eat = function ( ) { console .log ('吃一大盆' ) } Pig .prototype .sing = function ( ) {}Pig .prototype = { constructor : Pig , sing : function ( ) {}, dance : function ( ) {} } const animal = { head : 1 , sing : function ( ) {} } Pig .prototype = animalPig .prototype .constructor = Pig function Animal ( ) { this .head = 1 this .sing = function ( ) {} } Pig .prototype = new Animal ()Pig .prototype .constructor = Pig const peiqi = new Pig ('佩奇' , 8 ) const qiaozhi = new Pig ('乔治' , 7 )console .log (peiqi.__proto__ === Pig .prototype ) console .log (peiqi instanceof Object ) console .log (peiqi instanceof Array )
操作对象 查
1 2 3 console .log (obj.属性)console .log (obj['属性' ])console .log (obj.方法())
增
1 2 3 4 5 obj.name = 新值 Object .assign (obj, { name = 新值 })
删
遍历对象
1 2 3 4 5 6 7 8 9 10 11 12 for (let k in obj) { console .log (k) console .log (obj[k]) } const o = { uname : 'pink' , age : 18 }console .log (Object .keys (o)) console .log (Object .values (o))
拷贝对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 const obj = { uname : 'pink' , age : 18 , family : { baby : '小pink' } } const o = objconst o = { ...obj }const o = {}Object .assign (o, obj)function deepCopy (newObj, oldObj ) { debugger for (let k in oldObj) { if (oldObj[k] instanceof Array ) { newObj[k] = [] deepCopy (newObj[k], oldObj[k]) } else if (oldObj[k] instanceof Object ) { newObj[k] = {} deepCopy (newObj[k], oldObj[k]) } else { newObj[k] = oldObj[k] } } } deepCopy (o, obj) <script src="lodash.js" ></script> const o = _.cloneDeep (obj)const o = JSON .parse (JSON .stringify (obj))
对象解构 将对象的属性和方法快速批量赋值给一系列变量,形参必须等于属性或者方法名
1 2 3 const {uname, age} = {uname : '张三' , age : 18 }const {uname : username, age} = {uname : '张三' , age : 18 }
数组对象解构
1 const [{uname, age}] = [{uname : '张三' , age : 18 }]
多级对象解构
1 2 3 4 5 6 7 8 9 10 11 12 const person = [ { name : '佩奇' , family : { mother : '猪妈妈' , father : '猪爸爸' , sister : '乔治' }, age : 6 } ] const [{ name, family : { mother, father, sister } }] = person
内置对象 Math对象 1 2 3 4 function getRandom (min, max ) { return Math .floor (Math .random () * (max - min + 1 )) + min }
时间对象 获取时间
1 2 3 4 5 6 new Date ().toLocaleString ()new Date ().toLocaleDateString ()new Date ().toLocaleTimeString ()
时间戳 1970-1-1 00:00:00
起到现在的毫秒数
1 2 3 4 5 6 7 let date = new Date ()console .log (date.getTime ())console .log (+new Date ())Date .now ()
倒计时案例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 let now = +new Date ()let last = +new Date ('2021-8-29 18:30:00' )let count = (last - now) / 1000 let h = parseInt (count / 60 / 60 % 24 )h = h < 10 ? '0' + h : h let m = parseInt (count / 60 % 60 )m = m < 10 ? '0' + m : m let s = parseInt (count % 60 );s = s < 10 ? '0' + s : s
Web APIs DOM(文档对象模型) 元素 获取元素
1 2 3 4 document .querySelector ('CSS选择器' )document .querySelectorAll ('CSS选择器' )
通过节点关系获取元素
1 2 3 4 5 元素.parentNode 元素.children 元素.childNodes 元素.nextElementSibiling 元素.previousElementSibiling
设置/修改元素内容
1 2 3 4 5 6 7 8 9 10 11 12 13 document .write ('' )元素.innerText = 元素.innerHTML = 元素.value = 元素.disabled = true
创建/添加元素
1 2 3 4 5 6 7 8 9 10 document .createElement ('标签名' )元素.cloneNode (布尔值) 父元素.appendChild (子元素) 父元素.insertBefore (子元素, 插入位置下方的兄弟元素)
删除节点
清空表单
1 document .createElement ('form' ).reset ()
样式/属性 修改样式属性/类名
1 2 3 4 5 6 7 8 9 10 11 12 13 元素.style .样式属性 = 值 box.style .backgroundColor = 'red' 元素.className = '类名1 类名2' 元素.classList .add ('类名' ) 元素.classList .remove ('类名' ) 元素.classList .toggle ('类名' ) 元素.classList .contains ('类名' )
设置/修改元素属性
自定义属性
1 2 3 4 5 6 7 元素.setAttribute ('属性名' , 属性值) 元素.getAttribute ('属性名' ) 元素.dataset .xxx 元素.removeAttribute ('属性名' )
DOM事件 事件监听 1 2 3 4 5 6 7 事件源.addEventListener ('事件类型' , 事件处理函数(e), 是否捕获) 事件源.on 事件类型 = 事件处理函数 事件源.removeEventListener ('事件类型' , 事件处理函数(e), 是否捕获) 事件源.on 事件类型 = null
事件类型与事件对象 参考:
常用事件类型及属性:
click
input
blur
change
keyup
/keydown
mousemove
、mouseenter
/mouseleave
scroll
resize
load
所有资源加载完执行;DOMContentLoaded
给document加,DOM加载完执行,无需等待样式表、图像等完全加载
事件对象常用属性:
type
获取当前事件类型
clientX
/clientY
获取光标相对于浏览器可见窗口左上角的位置
pageX
/pageY
获取光标相对于整个网页左上角的位置
offsetX
/offsetY
获取光标相对于当前DOM元素左上角的位置
key
用户按下按键的值
事件流
1 2 3 4 事件对象.preventDefault () 事件对象.stopPropagation ()
事件委托 利用事件冒泡,给父元素添加事件,子元素可以触发,通过事件对象.target
可以获得需要触发的子元素
事件对象.target.id
子元素id
事件对象.target.tagName
子元素标签名
获取尺寸 scroll
scrollWidth
/scrollHeight
内容宽高,包括不可见部分
scrollTop
/scrollLeft
被页面卷去的头部与左侧长度(number,可修改)
offset
offsetWidth
/offsetHeight
元素盒子总宽高, 不包含margin
offsetTop
/offsetLeft
元素距离自己定位父级元素(没有则以文档左上角为准)的上、左距离(number,不可修改)
client
clientWidth
/clientHeight
元素可见宽高,不包括边框、滚动条等
clientTop
/clientLeft
上边框和左边框宽度(number,不可修改)
BOM(浏览器对象模型) 定时器 定时器-间歇函数
1 2 3 4 5 setInterval (函数, 间隔时间)let 变量名 = setInterval (函数, 间隔时间)clearInterval (变量名)
定时器-延时函数
1 2 3 4 5 setTimeout (回调函数, 等待毫秒数)let 变量名 = setTimeout (回调函数, 等待毫秒数)clearTimerout (变量名)
location对象 常用属性和方法
href
返回(当前页面的)整个 URL,赋值可实现网页跳转功能
search
获取URL?
及后的参数
hash
获取URL#
后的哈希值
navigator对象 访问浏览器的信息
Swiper插件 各种轮播图,中文官网
Ajax XMLHttpRequest GET请求
1 2 3 4 5 6 7 8 9 10 11 12 13 let xhr = new XMLHttpRequest ()xhr.open ('GET' , 'http://www.liulongbin.top:3006/api/getbooks' ) xhr.send () xhr.onreadystatechange = function ( ) { if (xhr.readyState === 4 && xhr.status === 200 ) { console .log (xhr.responseText ) } }
JSONP 通过script标签的src属性实现跨域请求,仅支持GET
1 2 3 4 5 6 7 8 <script> function abc (data ) { console .log ('JSONP响应回来的数据是:' ) console .log (data) } </script> <script src ="http://ajax.frontend.itheima.net:3006/api/jsonp?callback=abc&name=ls&age=30" > </script >
POST请求
1 2 3 4 5 6 7 8 9 10 11 12 13 14 let xhr = new XMLHttpRequest ()xhr.open ('POST' , 'http://www.liulongbin.top:3006/api/addbook' ) xhr.setRequestHeader ('Content-Type' , 'application/x-www-form-urlencoded' ) xhr.send ('bookname=水浒传&author=施耐庵&publisher=上海图书出版社' ) xhr.onreadystatechange = function ( ) { if (xhr.readyState === 4 && xhr.status === 200 ) { console .log (xhr.responseText ) } }
readyState属性
0
UNSENT (XMLHttpRequest 对象已被创建,但尚未调用 open方法)
1
OPENED (open()方法已经被调用)
2
HEADERS_RECEIVED (send()方法已经被调用,响应头也已经被接收)
3
LOADING (数据接收中,此时 response 属性中已经包含部分数据)
4
DONE Ajax 请求完成,这意味着数据传输已经彻底完成或失败
XMLHttpRequest 2 设置超时时间
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 let xhr = new XMLHttpRequest ()xhr.timeout = 30 xhr.ontimeout = function ( ) { console .log ('请求超时了!' ) } xhr.open ('GET' , 'http://www.liulongbin.top:3006/api/getbooks' ) xhr.send () xhr.onreadystatechange = function ( ) { if (xhr.readyState === 4 && xhr.status === 200 ) { console .log (xhr.responseText ) } }
FormData() 请求体(只存在于POST请求)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 var fd = new FormData ()fd.append ('uname' , 'zs' ) fd.append ('upwd' , '123456' ) var xhr = new XMLHttpRequest ()xhr.open ('POST' , 'http://www.liulongbin.top:3006/api/formdata' ) xhr.send (fd) xhr.onreadystatechange = function ( ) { if (xhr.readyState === 4 && xhr.status === 200 ) { console .log (JSON .parse (xhr.responseText )) } }
通过FormData()快速获取表单数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 var form = document .querySelector ('#form1' )form.addEventListener ('submit' , function (e ) { e.preventDefault () var fd = new FormData (form) var xhr = new XMLHttpRequest () xhr.open ('POST' , 'http://www.liulongbin.top:3006/api/formdata' ) xhr.send (fd) xhr.onreadystatechange = function ( ) { if (xhr.readyState === 4 && xhr.status === 200 ) { console .log (JSON .parse (xhr.responseText )) } } })
上传文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 <input type ="file" id ="file1" /> <button id ="btnUpload" > 上传文件</button > <br /> <img src ="" alt ="" id ="img" width ="800" /> <script > var btnUpload = document .querySelector ('#btnUpload' ) btnUpload.addEventListener ('click' , function ( ) { var files = document .querySelector ('#file1' ).files if (files.length <= 0 ) { return alert ('请选择要上传的文件!' ) } var fd = new FormData () fd.append ('avatar' , files[0 ]) var xhr = new XMLHttpRequest () xhr.open ('POST' , 'http://www.liulongbin.top:3006/api/upload/avatar' ) xhr.send (fd) xhr.onreadystatechange = function ( ) { if (xhr.readyState === 4 && xhr.status === 200 ) { var data = JSON .parse (xhr.responseText ) if (data.status === 200 ) { document .querySelector ('#img' ).src = 'http://www.liulongbin.top:3006' + data.url } else { console .log ('图片上传失败!' + data.message ) } } } })
axios 专注于网络数据请求的库GET请求
1 axios.get ('url' , { params : { } }).then (callback)
POST请求
1 axios.post ('url' , { }).then (callback)
通用写法
1 2 3 4 5 6 axios ({ method : '请求类型' , url : '请求的URL地址' , data : { }, params : { } }) .then (callback)
URL编码 1 2 3 4 encodeURI ('张三' )decodeURI ('%E5%BC%A0%E4%B8%89' )
本地存储 localStorage 永久,以键值对形式存储
1 2 3 4 localStorage .setItem (key,value)localStorage .getItem (key)
例
1 2 3 4 5 6 7 8 localStorage .setItem ('name' , '张三' ) localStorage .getItem ('name' ) let obj = { name : '张三' , age : 18 }localStorage .setItem ('obj' , JSON .stringify (obj)) JSON .parse (localStorage .getItem ('obj' ))
sessionStorage 临时,关闭浏览器失效,用法同localStorage
正则表达式 正则表达式在JavaScript中的使用
1 2 3 4 5 6 7 8 9 10 11 let reg = /前端/ let str = '我们大家都在学前端' reg.test (str) reg.exec (str) str.replace (/正则/g , '替换文本' )
组件库 ECharts 一个基于 JavaScript 的开源可视化图表库。ECharts官网
常用配置项
title
:标题组件
tooltip
:提示框组件
legend
:图例组件
toolbox
: 工具栏
grid
:直角坐标系内绘图网格
xAxis
:直角坐标系 grid 中的 x 轴
yAxis
:直角坐标系 grid 中的 y 轴
series
: 系列列表。
color
:调色盘颜色列表