ES

简介: ES

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是可遍历对象
image.png
什么是iterator,for of 由iterator封装而来

image.png

for of

for of是对iterator进行封装
image.png
for...of循环只会遍历出那些done为false时,对应的value值,可以与contine break一起使用

image.png

image.png

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))
//基本数据类型作为源对象,与对象的展开类似,先转换成对象,再合并

image.png
image.png

Object.keys()、Object.values()和Object.entries()获取键,值,全部的

image.png

image.png

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的两种导出和导入

image.png

  • 一个模块没有导出,也可以将其导入,被导入的代码都会执行一遍(基本可以忽略)
  • 一个模块只能有一个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.(属性/方法)
相关文章
|
前端开发 JavaScript Java
ES11,ES12,ES13
ES11,ES12,ES13
111 1
|
1月前
|
存储 JavaScript 前端开发
什么是Es6,有什么特点
什么是Es6,有什么特点
37 1
|
2月前
|
前端开发
关于es6
关于es6
13 0
|
7月前
|
存储 JavaScript 前端开发
ES6
ES6
50 1
|
前端开发 索引
ES7,ES8
ES7,ES8
66 0
ES6(二)
es6相关知识
71 0
|
JSON 资源调度 JavaScript
ES6 Day01
ES6 Day01
79 0
|
JavaScript 前端开发 Java
【ES6】初识
【ES6】初识
|
JSON JavaScript 前端开发
ES5和ES6的介绍
《前端基础》
435 0
|
JavaScript
浅谈一下ES6的提升
es6的提升 在es6之前,我们定义定义变量的时候,只能使用var关键字来定变量,这样有一个问题,var定义的变量会成为全局变量。