theme: fancy
highlight: agate
js与ES的关系
JavaScript(浏览器端) = ECMAScript(语法+API) + DOM+ BOM
const注意事项
- 使用const声明常量,一旦声明,就必须立即初始化,不能留到以后赋值
- const声明的基本类型不能被修改
const let var
var - 允许重复声明
- 变量提升
- window对象的属性和方法,全局作用域中,var 声明的变量,通过function声明的函
数,会自动变成window对象的属性或方法let、const 不会
let const
- 块级作用域
- 暂时性死区只要作用域内存在let、const, 它们所声明的变量或常量就
自动“绑定”这个区域,不再受到外部作用域的影响
let a=2;
let b=1;
function func(){
console.log(b);
console.log(a);
let a= 1;}
func();
输出b=1 输出a报错。a不会向外查找,在声明之前使用a,就会报错
模板字符串注意事项
- 模板字符串中,所有的空格、换行或缩进都会被保留在输出之中
- 想输出` /要在前面加/转义
- 模板字符串的注入${}
箭头函数
箭头函数结构
const/let函数名=参数 => 函数体箭头函数注意事项
- 单个参数可以省略圆括号
- 单行函数体可以同时省略{} 和return
- 如果箭头函数返回单行对象,可以在{}外面加上(),让浏览器不再认为那是函数体的花括号
canst add = (x, y) => {
return{
value:x + y
};
console.log(add(1, 1));
const add = (x, y) => ({
value:x + y})//会把对象的花括号当成函数的花括号解析
箭头函数不适合的场景
- 作为构造函数,箭头函数没有自己的this
- 需要this指向调用对象的时候
- 需要使用arguments的时候,箭头函数没有arguements
箭头函数的应用
this指向继承外层的this - 以前的方法var self=this
- 改为箭头函数自动继承外层this指向
解构赋值
什么是解构赋值解析某数据的结构,将我们想要的东西提取出来,赋值给变量
或常量数组解构默认值
// 1.默认值的基本用法
const[a,b]= []; .
const [a, b] = [undefined, undefined];
const[a = 1,b= 2]= [];
console.log(a, b); //1 2
//2.只有当一个数组成员严格等于(===)undefined 时,对应的默认值才会生效
//3.如果默认值是表达式,默认值表达式是惰性求值的,即如果有值则不执行默认值表达式
//跳过不需要的赋值只需要加个逗号,
对象解构赋值
// 1.模式(结构)匹配
// {}={}
// 2.属性名相同的完成赋值
const {
age, username } = {
username: 'Alex',age: 18 };
const {
age: age, username: username } = {
username: 'Alex', age: 18 };
//取别名
const{
age: age, username: uname} ={
username: 'Alex', age: 18] ;
// 3.将一个已经声明的变量用于解构赋值
//如果将一个已经声明的变量用于对象的解构赋值,整个赋值需在圆括号中进行
let x = 2;
let{
x}={
x:1};//会报错
{
x}={
x:1}//会把第一个花括号当成代码块,需要加一个小括号({x}={x:1})
// 4.函数参数的解构赋值
1 const logPersonInfo = user => console.log(user.username,user.age);
2 const logPersonInfo = ({
age,username})=>console.log(username,age);
logPersonlnfo({
username: alex', age: 18 });
函数参数的默认值
默认值的生效条件不传参数,或者明确的传递undefined作为参数,只有这两种情况下,默认值才会生效
const multiply= (x,y=1)=> x*y;
console.log(multiply(2, null);//0
console.log(multiply(2, undefined));//2
函数参数默认值的应用
const logUser = ({
username='zhangsan',age =0,sex='male'} = {
})=>console.log( username, age, sex);
logUser({
}),logUser()都能直接调用
logUser()相当于logUser(undefined) undefined(null)不能被解构赋值
剩余参数
剩余参数(数组)即使没有值也是空数组
const add = (x ,y, ...args) = >console.log(x, y, args);
剩余函数注意事项
const add = (...args) => {
};
// 箭头函数的参数部分即使只有一个剩余参数,也不能省略圆括号
//剩余参数只能是最后一个参数】
//使用剩余参数替代 arguments 获取实际参数,箭头函数没有arguements
数组展开运算符的应用
- 复制数组
let a=[1,2]
let b=[...a]
- 字符串可以按照数组的形式展开
对象展开运算符
- 对象不能直接展开,必须在{} 中展开 {...apple}
- 字符串都可以转{...'lee'}//序号会当成他的属性名 [...'lee']
- 复制对象
Set
- Set中不能有重复的成员
- Set没有下标去标示每一个值,所以Set是无序的,也不能像数组那样通过下标去访问Set的成员
- Set可以给字符串,数组去重
console.log([...new Set([1, 2, 1]]);
console.log([...new Set('abbacbd')].join(''));
Set方法
const s = new Set();
//1.add一次只能加一个,可以链式调用
//2.has判断是否含有某个元素
//3.delete删除不存在的元素什么都不会发生,不会报错
//4.clear清除全部元素
//5.forEach
s.forEach(function (value, key,set) {
},documnet
// Set中value = key,第二个参数代表第一个回调函数的this指向,set代表s本身
//6.属性:size
Set构造函数的参数
- 数组
- arguements,nodelist,Set,字符串
- 复制新Set
const s = new Set([1,2,1]);
new Set(s)
注意事项
Set对重复值的判断基本遵循严格相等(===),但是对于NaN的判断与===不同,Set 中NaN等于NaN
Map
Map和对象的区别
对象一般用字符串当作键,基本数据类型,引用数据类型都可以当成键
Map方法
使用set添加的新成员,键如果已经存在,后添加的键值对覆盖已有的
get获取不存在的成员,返回undefined
has delete clear forEach 属性size 对象没有类似的属性
Map参数
只能传二维数组,而且必须体现出键和值
const m=new Map([[a,b],[c,d]])
Map注意事项
Map对重复值的判断基本遵循严格相等(===),但是对于NaN的判断与===不同,Map 中NaN等于NaN
iterator遍历器
对象非原生可遍历
it是可遍历对象
什么是iterator,for of 由iterator封装而来
for of
for of是对iterator进行封装
for...of循环只会遍历出那些done为false时,对应的value值,可以与contine break一起使用
forin forof
- forin遍历对象,forof遍历数组,forof不能遍历对象
- forin循环得到的是键,forof循环得到的是值
- forin会遍历原型链
ES6新增方法
includes includes认为NAN===NAN
console.log('abc'.includes('ab'));//返回布尔值true
还有第二个参数表示开始搜索的位置,默认是0
padStart padEnd一个在头一个在尾
console.log('x'.padStart(5,'ab'))//ababx
console.log('x'.padEnd(4,'ab'))//abax
原字符串的长度,等于或大于最大长度,不会消减原字符串,字符串补全不生效,返回原字符串
console.log('xxx'.padStart(2,'ab'))//xxx
- 如果省略第二个参数,默认使用空格补全长度
- 用来补全的字符串与原字符串长度之和超过了最大长度,截去超出位数的补全字符串,原字符串不动
- 应用:日期格式
// 2020-10-10 . // 2020-01-01 console.log('10'.padStart(2, 0)); console.log('1'.padStart(2, 0));
trimStart trimEnd
清除字符串的首尾空格,中间的空格不会清除
console.log(' a b c'.trimStart)//a b c
Array.from()
将类数组,set类型转换成数组
Object.assign()
合并对象Object.asign(目标对象,源对象1,源对象...)
// Object.assign直接合并到了第一个参数中, 返回的就是合并后的对象
console.log(Object.assign(apple,pen))
//console.log({...apple,...pen})
//如果不想改变第一个参数console.log(Object.assign({},apple,pen))
//基本数据类型作为源对象,与对象的展开类似,先转换成对象,再合并
Object.keys()、Object.values()和Object.entries()获取键,值,全部的
promise
promise是异步操作的解决方案,一般用来解决层层嵌套的回调函数(回调地狱)
基本使用
先实例化Promise,接收一个箭头函数,箭头函数接收两个参数resolve,reject,在函数体里执行resolve()代表成功,reject()代表失败,then接收两个回调函数,成功执行第一个回调,失败执行第二个回调,resovle,reject可以传入参数,由.then里的回调函数参数接受
- Promise有3种状态,一开始是pending (未完成),执行resolve,变成fulfilled(resolved),已成功,执行reject,变成rejected,已失败
- Promise的状态- -旦变化, 就不会再改变了
.then
const p = new Promise((resolve, reject) => {
resolve()
})
p.then(
//这个then的返回值是成功还是失败?
() => {
console.log('success')
//return undefined
//在then的回调函数中,return后面的东西,会用Promise包装一下
//等价于
return new Promise((resolve, reject) => {
//默认返回的永远都是成功状态的Promise对象
resolve(undefined)
//失败只能直接设置
return new Promise((resolve, reject) => {
reject()
})
})
},
() => {
console.log('error')
}
).then(
() => {
console.log('22')
},
() => {
}
)
catch
- catch()可以捕获它前面的错误
- 只要then,catch中没有报错,他们返回的是成功的回调。
- 一般来说我们只需要成功的回调,所以我们只需要写成功的回调,catch专门用来处理rejected状态
- catch本质是then的特例 then(null,err=>{})
- 一般总是建议,Promise 对象后面要跟catch方法,这样可以处理Promise内部发生的错误
.catch(err=>{
console.log(err)})
finally
执行完promise链,无论是否成功都会执行
promise.resolve / promise.reject
new Promise((resolve, reject) => {
resolve('传递的参数')
})
//等价于,简写形式也能传递参数
Promise.resolve('传递的参数')
new Promise((resolve, reject) => {
resolve('传递的参数')
}).then((data) => {
console.log(data)
})
//等价与
Promise.resolve('传递的参数').then((data) => {
console.log(data)
})
Promise.all()
- Promise.all()的状态变化与所有传入的Promise实例对象状态
有关 - 所有状态都变成resolved,最终的状态才会变成resolved
- 只要有一个变成rejected,最终的状态就变成rejected
- 参数是数组
Promise.race()
- Promise.race()的状态取决于第一个完成的Promise实例对象,如果第一个完成成功了,那最终的就成功;如果第一个完成的失败了,那最终的就失败
Promise.allSettled()
- Promise.allSettled()的状态与传入的Promise状态无关
- 永远都是成功的
- 它只会忠实的记录下各个Promise的表现
async await
执行async函数,返回promise对象,await相当于promise的then
await后面可以接一个异步任务或者Promise
async function fn() {
for (let index = 0; index < 5; index++) {
let ms = Math.random()
await setTimeout(() => {
//不知道为什么这里不是同步
console.log(index)
}, ms * 1000)
}
}
fn()
async function fn() {
for (let index = 0; index < 5; index++) {
let ms=Math.random();
await new Promise((resolve,reject)=>{
//Promise是微任务,等他执行完才会执行后面的语句
setTimeout(()=>{
console.log(index)
resolve()},ms*1000)
})
}
}
fn()//01234
class
类名一般首字母大写
class Person {
//实例化时执行构造方法,构造方法可以不写默认什么都不执行
constructor() {
//一般在构造方法中定义属性,方法不在构造方法中定义
}
}
const p = new Person()
类与构造函数
- typeof 类名 function class本质是一个函数
```js
//类
class Person {
//实例化时执行构造方法,构造方法可以不写默认什么都不执行
constructor(name) {
//一般在构造方法中定义属性,方法不在构造方法中定义
this.name = name
}
speak() {
console.log(this.name + ' speak')
}
}
//构造函数
function Person(name) {
this.name = name
}
Person.prototype.speak = function () {}
### 静态方法
```js
class Person {
age=999
constructor(name) {
this.name = name
}
speak() {
console.log(this.name + ' speak')
}
static speak(){
console.log('speak')
}
}
Person.speak()//直接调用
extents
class Person {
age = 999
constructor(name) {
this.name = name
}
speak() {
console.log(this.name + ' speak')
}
static speak() {
console.log('speak')
}
}
class my extends Person {
constructor(name) {
//super放在最前面,执行父类的构造方法
super(name)
}
}
const a = new my('zhang')
console.log(a.speak())
super
作为函数调用super()
- 代表父类的构造方法,只能用在子类的构造方法中,用在其他地方就会报错
- super虽然代表了父类的构造方法,但是内部的this指向子类的实例
在constructor,或一般函数中使用super.函数名() - super代表父类的原型对象Person.prototype
- 定义在父类实例上的方法或属性,是无法通过super调用的
- 通过super调用父类的方法时,方法内部的this指向当前的子类实例
在静态方法中使用 - 指向父类,而不是父类的原型对象
- 通过super调用父类的方法时,方法内部的this指向当前的子类,而不是子类的实例
ES Module
Module的两种导出和导入
- 一个模块没有导出,也可以将其导入,被导入的代码都会执行一遍(基本可以忽略)
- 一个模块只能有一个export default,只能导出一个 import时名字可以随便取
- 多个导出export {age,...},import {age,....}都要加花括号,并且名字不能随便取
- export导入导出起别名 名字 as 另一个名字
- 整体导入import * as 别名 form XXXX
- export和export default可以同时存在,这种情况下导出import (export default导出的),{export 导出的} from XXXX,一定是export default导出的放在前面
注意事项
- 模块中最外层的this指向undefined
- import命令具有提升效果,会提升到整个模块的头部,率先执行
- import执行的时候,代码还没执行
commonjs module
module.exports
用于导出一个exports
导出多个,不能一起用- 导入
const a = require('./a');
a.(属性/方法)