学习笔记之ES6
- 1. ECMAScript简介
- 2. let和const命令
- 3. 变量的解构赋值
- 4. 字符串的扩展
- 5. 正则的扩展
- 6. 数值的扩展
- 7. 函数的扩展
- 8. 数组的扩展
- 9. 对象的扩展
- 10. 对象的新增方法
- 10.1.Object.is()用途:比较两个值是否严格相等。
- 10.2.Object.assign():将源对象复制到目标对象。
- 10.3.Object.getOwnPropertyDescriptors():正确拷贝get属性和set属性。
- 10.4.__proto__属性,Object.setPrototypeOf()(写),Object.getPrototypeOf()(读)
- 10.5.Object.keys(),Object.values(),Object.entries()
- 10.6.Object.fromEntries():用于将一个键值对转为对象(相当于Object.entries()的逆操作)。
- 11. Symbol
- 12. Set和map数据结构
- 13. Proxy
- 14. Reflect
- 15. Promise对象
- 16. Iterator和for...of循环
- 17. Generator函数的语法
- 18. Generator函数的异步应用
- 19. async函数
- 20.
来源: http://es6.ruanyifeng.com/#README
1. ECMAScript简介
2. let和const命令
2.1. let命令
基本用法:let命令用来声明变量,用法类似于var,区别所声明的变量只在let命令所在代码块内有效。
暂时性死区:在代码块内,使用let命令声明变量之前,该变量都是不可用的。
不存在变量提升:var会在变量未声明前使用,值为undefined;而使用let进行定义,在未声明前使用会报错。
不允许重复声明:let不允许在相同作用域内重复声明同一个变量。
2.2. 块级作用域
外层作用域无法读取内层作用域的变量。
内层作用域可以定义外层作用域的同名变量。
2.3. const命令
基本用法:声明一个只读常量,一旦声明,常量值不可以改变(注:只申明不赋值会报错);若声明的是一个数组,数组的项可以改变,整个数组不行。只声明不赋值会报错。
暂时性死区:(同let命令 )
不可重复声明:(同let命令)
Object.freeze方法:冻结const声明的对象;对象的属性也可以冻结。
ES6声明变量有六种方式:var命令、function命令、let命令、const命令、import命令、class命令。
2.4. 顶层对象的属性
顶层对象:在浏览器环境指的是window对象,在node指的是global对象。
其中var声明的全局变量是顶层对象;Let声明全局变量不是顶层对象。如下所示:
var a = 1;
window.a//1
let b = 2;
window.b//undefined
2.5 globalThis对象
3. 变量的解构赋值
3.1.数组的解构赋值
基本用法:从数组和对象中提取值,对象进行赋值,有序;解构不成功,变量值为undefined。
对数组进行赋值时,右边的值本身不具备iterator接口或转为对象不具备iterator接口都会报错。
结构赋值允许指定默认值。
例子①:
let [foo] = [];
let [bar, foo] = [1];
以上两种情况都属于解构不成功,foo的值都会等于undefined。
例子②:
let [x, y] = [1, 2, 3];
x // 1
y // 2
let [a, [b], d] = [1, [2, 3], 4];
a // 1
b // 2
d // 4
上面两个例子,都属于不完全解构,但是可以成功。
3.2.对象的解构赋值
简介:对象的属性没有次序,变量必须与属性同名,才能去得到值;若解构失败,变量值为undefined。
对象解构的内部机制:先找到同名属性,然后再赋给对应的变量。真正被赋值的是后者,而不是前者。如:
let{foo:baz} = {foo:'aaa',bar:'bbb'};
baz//"aaa"
foo//error:foo is not defined
(foo是匹配,baz是变量)
对象的解构赋值可以去到继承的属性:
const obj1 = {};
const obj2 = {foo:'bar'};
Object.setPrototypeOf(obj1,obf2);
foo//"bar"
上面代码中,对象obj1的原型对象是obj2。foo属性不是obj1自身的属性,而是继承自obj2的属性,解构赋值可以取到这个属性。
注意:大括号不可以写在行首,会报错。应该在整个解构赋值语句加上圆括号。
//错误的写法
let x;
{x} = {x:1};
//正确的写法
let x;
({x} = {x:1});
3.3.字符串的解构赋值
字符串被转成类似数组的对象,再赋值。
3.4.数值和布尔值的解构赋值
先转为对象,再赋值。
3.5.函数参数的解构赋值
3.6.圆括号问题
不能使用圆括号的情况:
①变量声明语句
②函数参数
③赋值语句的模式部分(区别于3.2的注意点)
//以下三种全部报错
[({p:a}),{x:c}] = [{},{}];
({p:a}) = {p:42};
([a]) = [5];
可以使用圆括号的情况只有一种:赋值语句的非模式部分 。
//以下三个为正确的写法
[(b)] = [3];
({p:(d)} = {});
[(parseInt.prop)] = [3];
赋值语句的模式部分与非模式部分的区别:模式是取数组第一个成员;模式是p,而不是d;
3.7.用途
交换变量值;从函数返回多个值;函数参数的定义;提取json数据;函数参数的默认值;遍历map结构;输入模块的指定方法
4. 字符串的扩展
4.1.
5. 正则的扩展
5.1.RegExp构造函数
参数是字符串,第二个参数表示正则表达式的修饰符:RegExp(‘xyz’, ‘i’)。
参数的正则表达式,返回原有的正则表达式:RegExp(/xyz/i)。
参数第一个是正则对象,第二个参数则会覆盖正则的修饰符:RegExp(/xyz/ig,’i’)。
5.2.字符串的正则方法
5.3.u修饰符
5.4.RegExp.prototype.unicode属性
5.5.y修饰符
y修饰符和g修饰符类似,都是全局匹配,后一次匹配从上一次匹配成功的下一个来时位置开始;区别g只要剩余位置有匹配就可,而y要第一位置才可。
5.6.RegExp.prototype.sticky属性
表示是否设置了y修饰符
5.7.RegExp.prototype.flags属性
返回正则表达式的修饰符
5.8.s修饰符:dotAll模式
6. 数值的扩展
6.1.二进制和八进制表示法
基本用法:用前缀0b(或0B)和0o(或0O)表示。
7. 函数的扩展
7.1.函数参数的默认值
参数变量是默认声明的,不能用let或const再次声明。
默认参数:采用惰性求值方式。
参数默认值的位置:当有默认值是,调用其方法也因在对应参数写上undefined。
函数的length属性:length属性的返回值,等于函数的参数个数减去指定默认参数个数;如果默认参数不是尾参数,返回值不再计入后面的参数。
7.2.rest参数(…a)
rest参数后不能有其他的参数。
函数的length属性,不包括rest参数。
7.3.严格模式
基本用法:在全局中设置严格模式;函数包在一个无参数的立即执行的函数里面。
报错情景:函数参数使用了默认值、解构赋值、扩展运算符,函数内部设置了严格模式。
7.4.name属性
7.5.箭头函数
基本用法:
①箭头函数不需要参数或需要多个参数时,使用一个圆括号代表参数部分。
②箭头函数的代码块部分多于一条语句时,使用大括号将它们括起来,并使用return语句返回。
③箭头函数返回一个对象时,必须在对象外面加上括号,否则报错。
注意事项:
①函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。
②不可以用构造函数(new命令)
③不可以使用arguments对象。
④不可以使用yield命令。
不适用的场合:
①定义对象的方法,且该方法内部包括this,则不能用。
②需要动态this的时候,也不能用。
嵌套的箭头函数
7.6.尾调用优化
基本用法:只保留内层函数的调用帧。
7.7.函数参数的尾逗号
8. 数组的扩展
8.1.扩展运算符(…)
含义:扩展运算符是三个点(…)。
用途:主要用于函数的调用。
用法:后可放置表达式。
扩展运算符的应用:
①复制数组:例如const a1 = [1,2];复制a1的方法有
(1)const a2 = […a1];(2)const[…a2 = [a1];
②合并数组:[…数组1,…数组2,数组3]
③与解构赋值结合
若用于数组的解构赋值,只能放在最后一位。
④字符串:可以将字符串转为真正的数组。
⑤实现可iterator接口的对象
⑥map 和 set 结构,generator函数这三个都有iterator接口,都可以使用扩展运算符。
8.2.Array.from()
用途:将两类对象转为真正的数组(数组的对象和可遍历的对象)
8.3.Array.of()
用途:用于将一组值转换为数组。
8.4.数组实例的copyWithin()
Array.prototype.copyWithin(target, start = 0, end = this.length)
其中:target(必选):从该位置开始替换数据。Start(从该位置开始)和end(到该位置前停止读取数据)为可选。
8.5.数组实例的find()和 findIndex()
find()是查找出第一个符合条件的数组成员没有返回undefined;findIndex()没有返回-1。
8.6.数组实例的fill():用于 填充一个数组。
8.7.数组实例的entries(),key()和values();分别为键值对,键名和键值。
8.8.数组实例的includes():表示某个数组是否包含给定的值.
8.9.数组实例的 flat(),flatMap();表示拉平的层数,默认1层。
9. 对象的扩展
10. 对象的新增方法
10.1.Object.is()用途:比较两个值是否严格相等。
10.2.Object.assign():将源对象复制到目标对象。
10.3.Object.getOwnPropertyDescriptors():正确拷贝get属性和set属性。
10.4.__proto__属性,Object.setPrototypeOf()(写),Object.getPrototypeOf()(读)
10.5.Object.keys(),Object.values(),Object.entries()
10.6.Object.fromEntries():用于将一个键值对转为对象(相当于Object.entries()的逆操作)。
11. Symbol
11.1.概述
表示独一无二的值;即使参数相同,也不相等。用于常量状态识别。
11.2.作为属性名的symbol
11.3.消除魔术字符串
魔术字符串的特征:在代码中多次出现,与代码形成“强耦合”。
消除方法:把魔术字符串写成一个变量。
11.4.属性名的遍历
11.5.Symbol.for(),Symbol.keyFor()
其中Symbol.for()和Symbol.keyFor()都表示重新使用同一个symbol值。
11.6.模块的singleton模式
11.7.内置的symbol值
12. Set和map数据结构
12.1.set
基本用法:成员值都是唯一的,set结构不会添加重复的值;成员什么都可以。
属性和遍历操作方法:两个属性和四个方法(keys();values();entries();forEach())。
12.2.WeakSet
含义:成员值都是唯一;且成员只能是对象。
12.3.map
Map的键实际上是跟内存地址绑定的,只要内存地址不一样,就视为两个键。
12.4.WeakMap
只接受对象作为键名。
没有遍历操作方法,只有四个方法(get()、set()、has()、delete())。
13. Proxy
13.1.概述
Proxy可以理解为拦截器。
13.2.Proxy实例方法
Apply():拦截函数的调用,接受三个参数(目标对象、目标对象的上下文对象和目标对象的参数数组。)
Has():拦截HasProperty操作,接受两个参数(目标对象、需查询的属性名)。
Construct():拦截new命令,接受两个参数(目标对象、构造函数的参数对象)。
DeleteProperty():拦截delete操作。
DefineProperty():拦截Object.defineProperty操作。
getOwnPropertyDescriptor():拦截Object.getOwnPropertyDescriptor()操作。
ownKeys():拦截对象自身属性的读取操作。
preventExtensions():拦截Object.preventExtensions()。
setPrototypeOf():拦截Object.setPrototypeOf方法。
13.3.Proxy.revocable()
该方法返回一个可以取消的Proxy实例。
13.4.this问题
14. Reflect
14.1.概述
14.2.静态方法
15. Promise对象
15.1.promise的含义
含义:简单的说就是一个容器。
特点:对象的状态不受外界影响;状态改变,就不会再变。
15.2.基本用法
16. Iterator和for…of循环
16.1.Iterator(遍历器)概念
17. Generator函数的语法
17.1.简介
特征:function关键字与函数名之间有一个星号;函数体内部使用yield表达式,定义不同的内部状态。
在generator函数内部,调用另外一个generator函数,默认是没有效果的。
Yield表达式:表示暂停;只能在generator函数里面使用,其他地方会报错;用在另外一个表达式中,必须放在圆括号里面。