es6知识点整理
let和const
- let 声明变量
- 不存在变量提升
- 不能在变量声明语句之前去使用变量
- 在变量声明前使用变量会报错
- 暂时性死区
存在暂时性死区,即在变量声明语句之前的区域和声明语句外的块级作用域下是不能使用该变量的 - 不允许重复声明
在声明变量之后,不能重复声明该变量,只能进行赋值操作 - 块级作用域
ES6中,以{}来划分块级作用域,每一个{}内都是一个块级作用域。
- 不存在变量提升
- const声明常量
- const声明的常量拥有let声明变量的所有特性
但是在其声明后就不能进行赋值操作了。 - const声明的变量不能进行更改
严格意义上讲,是const声明的变量指向的那个地址不能更改了
引用数据类型可以通过改变堆中的数据来实现更改
- const声明的常量拥有let声明变量的所有特性
变量的解构赋值
- 数组的解构赋值
- 基本使用
let [a,b,c] = [1,2,3]
在等号两边的模式相同的情况下,可以将右边数组的值提出来,赋值给等号左边对应的变量 - 默认值
允许给变量设置默认值,在解构失败或变量被赋值undefined时,会触发默认值
注意,null不会触发默认值
- 基本使用
对象的解构赋值
- 基本使用
let {a,b,c} = {a:1,b:2,c:3}
基本上与数组一样,注意对象是使用{},并且是通过key值来对应赋值的,并不是以相对位置的
因为对象本身就是无序的 - 默认值
允许给变量设置默认值,在解构失败时或变量被赋值undefined时,会触发默认值
注意,null不会触发默认值在设置默认值后,只有在解构失败或者变量被赋值undefined时,才会触发默认值
需要注意的是,必须严格等于undefined,null不行
- 基本使用
字符串的解构赋值
- 了解基本的应用方式
const [a, b, c, d, e] = 'hello';
变量会依次被字符串对应的字符赋值
- 了解基本的应用方式
- 函数参数的解构赋值
- 作用
当形参列表和传参时的实参列表采用同样的模式时,会依次将实参传入形参中 - 应用场景
```javascript function add([x, y]){ return x + y; }
- 作用
add([1, 2]); // 3
```javascriptfunction move({x = 0, y = 0} = {}) {return [x, y];}move({x: 3, y: 8}); // [3, 8]move({x: 3}); // [3, 0]move({}); // [0, 0]move(); // [0, 0]
模板字符串
- 模板字符串的使用方式
使用反引号````,而且可以在反引号内自由换行,并且可以传入参数 - 字符串中传入变量
${}在模板字符串中使用${}符号,来将变量放入花括号内解析 - 花括号中使用表达式
在花括号内还可以使用表达式,可以将任意的JavaScript表达式进行运算,以及引用对象属性;
也可以调用函数
函数的扩展
- 函数参数默认值
在ES6中允许函数使用参数默认值,当实参个数小于形参个数时,会触发函数参数的默认值;
定义了默认值的函数参数应该被放在函数参数的最后,方便查看
可以将函数参数的默认值规定为一个错误,这样当调用这个函数时没有传参就可以抛出一个错误 - rest参数
可以代替argument来获取多余参数,需要使用一个变量来与rest参数配合使用
具体使用方法:...rest参数- 这个变量应该是一个数组,用于存放多余的参数
- rest就是一个标准的数组,数组的方法都可以直接使用
- 下面是一个arguments和rest的比较
```javascript // arguments变量的写法 function sortNumbers() { return Array.from(arguments).sort(); }
// rest参数的写法 const sortNumbers = (…numbers) => numbers.sort();
3. 箭头函数1. 简化写法 <br />如果箭头函数不需要参数或需要多个参数,就使用一个圆括号代表参数部分。<br />如果箭头函数的代码块部分多于一条语句,就要使用大括号将它们括起来,并且使用`return`语句返回。<br />由于大括号被解释为代码块,所以如果箭头函数直接返回一个对象,必须在对象外面加上括号,否则会报错。```javascriptlet fn = a => a;//相当于之前的let fn = function (a){return a;}
- 使用场景
- 不需要使用动态的this
- 对象的方法中不使用this的情况
- this
- 箭头函数没有自己的this对象
- 在箭头函数中的this是指向上层作用域的this
- 箭头函数的this相比于普通函数的this是比较固定的
数组相关
关于数组能够提高代码效率的写法
- Array.at(index)
可以从末尾开始获取下标,例如:Array.at(-1) 获取最后数组最后一项;
假值处理
当从后端获取数据时,可能会出现空值或者没有对应的数据返回的情况,需要进行空值兼容
- 空值合并运算符(
??)
// 可选链 const name = res?.result?.data?.userInfo?.name || ‘’
可选链操作符 ( ?. ) 允许读取位于连接对象链深处的属性的值,而不必明确验证链中的每个引用是否有效。?. 操作符的功能类似于 . 链式操作符,不同之处在于,在引用为空 (null 或者 undefined) 的情况下不会引起错误,该表达式短路返回值是undefined。<a name="gkqQv"></a>## 通过数组每个对象的某个key值将一个数组分成多个数组```javascriptconst provinceObj = orderList.group( ({ province }) => province );
对象的语法糖
对象属性的简化写法
- 当属性名和变量名相同时,可以在对象中直接写一个变量名来代替之前的键值对;
const a = 100;const b = 200;//简化后const obj = {a,b}//等同于const obj = {a:a,b:b}
- 当属性名和变量名相同时,可以在对象中直接写一个变量名来代替之前的键值对;
方法的简化写法
可以省略掉:function
```javascript const obj = { fn : function(){return "Hello!";
} }
//等同于 const obj = { fn(){ return “Hello!”; } }
3. super关键字<br />类似于this,但是super关键字指向当前对象的原型对象<a name="yR7wd"></a>## set和map1. set1. 创建set<br />`const s = new Set();`<br />Set是新的数组结构,类似于数组,但是Set成员的值没有重复的1. 属性和方法1. size 返回实例的成员总数1. add() 添加某个值,返回Set结构本身1. delete 删除某个值,返回一个布尔值,表示删除操作是否成功1. has 返回一个布尔值,表示Set成员中是否包含这个值1. clear 清除所有成员,没有返回值3. 遍历操作1. keys() 返回键名的遍历器1. values() 返回键值的遍历器1. entries() 返回键值对的遍历器1. forEach() 使用回调函数遍历每个成员2. map1. 含义和基本用法<br />类似于对象的一种新的数据结构,相对于对象的“键值对”,Map也支持“值值对”,更加灵活的存储数据的结构,1. 方法1. set(key,value); 设置Map对象中的key,对应的值为value;当前Map有这个key就更新value,没有就添加1. get(key);读取key对应的键值,并返回,如果找不到就返回undefined1. has(key);返回一个布尔值,表示某个键是否在当前Map对象中1. delete();删除某个key,返回一个布尔值,表示删除操作是否成功1. clear();清除所有Map对象的成员,没有返回值3. 遍历操作1. keys();返回键名的遍历器1. values() 返回键值的遍历器1. entries() 返回所有成员的遍历器1. forEach() 遍历Map的所有成员<a name="n0xwr"></a>## symbol1. symbol 的特点<br />symbol值是通过Symbol函数生成。<br />`const s = Symbol()`,会让s变成独一无二的值,而且会改变它的数据类型为`Symbol`;1. 创建symbol<br />const s = Symbol(),通过Symbol函数生成1. symbol的使用- 在使用Symbol函数时,在`Symbol()`前不能使用new关键字,因为Symbol是一个新的原始类型而不是一个新的对象- 在使用Symbol函数时,可以在函数中传入参数,来作为这个Symbol类型参数的说明,用来区分- Symbol的值不能与其他类型的值进行运算,否则报错- Symbol可以强制转换为字符串类型- 也可以转换为布尔型,但是无法转化为数字型<a name="xC8lW"></a>## Promise1. Promise的应用场景和解决的问题<br />Promise 是异步编程的一种解决方案,比传统的解决方案(回调函数和事件)更合理和更强大。<br />所谓`Promise`,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理。1. Promise中的方法1. then方法 为Promise实例添加状态改变时的回调函数。它的第一个参数是resolved状态的回调函数,第二个参数是,rejected状态的回调函数。<br />即`then(resolved状态下的回调函数,rejected转台下的回调函数)`1. catch方法<br />用于指定发生错误时的回调函数,可以放在链式的最后来捕捉错误1. finally方法<br />这个方法是用于Promise对象最后状态如何,都会执行的操作,可以用来执行清理操作1. all方法<br />用于将多个Promise实例,包装成一个新的Promise实例。<br />上面代码中,`Promise.all()`方法接受一个数组作为参数,`p1`、`p2`、`p3`都是 Promise 实例,如果不是,就会先调用下面讲到的`Promise.resolve`方法,将参数转为 Promise 实例,再进一步处理。另外,`Promise.all()`方法的参数可以不是数组,但必须具有 Iterator 接口,且返回的每个成员都是 Promise 实例。<br />`p`的状态由`p1`、`p2`、`p3`决定,分成两种情况。<br />(1)只有`p1`、`p2`、`p3`的状态都变成`fulfilled`,`p`的状态才会变成`fulfilled`,此时`p1`、`p2`、`p3`的返回值组成一个数组,传递给`p`的回调函数。<br />(2)只要`p1`、`p2`、`p3`之中有一个被`rejected`,`p`的状态就变成`rejected`,此时第一个被`reject`的实例的返回值,会传递给`p`的回调函数。1. race方法<br />也是将多个Promise实例,包装成一个新的Promise实例<br />只要`p1`、`p2`、`p3`之中有一个实例率先改变状态,`p`的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给`p`的回调函数。<br />`Promise.race()`方法的参数与`Promise.all()`方法一样,如果不是 Promise 实例,就会先调用下面讲到的`Promise.resolve()`方法,将参数转为 Promise 实例,再进一步处理。1. resolve方法<br />将现有对象转为Promise对象- 参数是一个Promise实例,则不作为,返回这个实例- thenable对象。具有then方法的对象,将这个对象转为Promise对象,并且立即执行thenable对象的then()方法- 不具有then()方法的对象,或者不是个对象<br />返回一个新的Promise对象,状态为resolved- 没有参数<br />直接返回一个resolved状态的Promise对象<a name="i28Fb"></a>## async/await1. async / await解决的问题<br />使异步操作变得更简洁。是异步函数的语法糖1. 具体使用方法```javascriptasync function fn(){const promiseA = await 返回Promise对象的函数const promiseB = await 返回Promise对象的函数...}
class
- class的本质
语法糖。简化生成实例对象的方法 使用方式
class Point {constructor(x, y) {this.x = x;this.y = y;}toString() {return '(' + this.x + ', ' + this.y + ')';}}
constructor
是类的默认方法,在通过new命令生成对象实例时,自动调用该方法;
如果类中没有该方法,则JS引擎会自动为他添加一个空的constructor()方法- 属性和方法的设置
可以定义在constructor()方法里面的this上面,也可以定义在类的最顶层 继承
通过extends关键字实现继承class ColorPoint extends Point { // 前面是子类,后面是父类constructor(x, y, color) {super(x, y); // 调用父类的constructor(x, y)this.color = color;}toString() {return this.color + ' ' + super.toString(); // 调用父类的toString()}}
super方法
既可以当做函数使用,也可以当做对象使用- 作为函数被调用时,代表父类的构造函数,子类的构造函数必须执行一次super函数
- 作为对象,在普通方法中,指向父类的原型对象;在静态方法中,指向父类
- 静态属性和方法
指的是Class本身的属性,而不是定义在实例对象上的属性
上面的写法为Foo类定义了一个静态属性prop。
目前,只有这种写法可行,因为 ES6 明确规定,Class 内部只有静态方法,没有静态属性。现在有一个提案提供了类的静态属性,写法是在实例属性的前面,加上static关键字。
这个新写法大大方便了静态属性的表达。
```javascript class Foo { }
Foo.prop = 1; Foo.prop // 1
```javascriptclass MyClass {static myStaticProp = 42;constructor() {console.log(MyClass.myStaticProp); // 42}}
// 老写法class Foo {// ...}Foo.prop = 1;// 新写法class Foo {static prop = 1;}
