一、let、const
let与var的区别
1、let受块级作用域限制,var仅受函数作用域限制
2、let不存在变量提升
3、let存在暂时性死区
4、let不允许重复声明
5、let声明的全部变量不属于顶层对象(window、global,es2020还引入统一的globalThis指向顶层对象)
const是无法改变值的let,且需要在声明时复制
二、解构赋值
解构赋值的规则是,只要等号右边的值不是对象或数组,就先将其转为对象比如:
1、字符串:被转换成了一个类似数组的对象
2、数值和布尔值:包装为具有toString属性的对象
let {toString: s} = 123;
let {toString: s} = true;
注:undefined和null无法转为对象,所以对它们进行解构赋值,都会报错
解构赋值的使用
1、交换变量的值,不在需要中间变量
[x, y] = [y, x]
2、从函数返回多个值
function example() {
return {
foo: 1,
bar: 2
};
}
let { foo, bar } = example();
3、按需引入
const { SourceMapConsumer, SourceNode } = require("source-map");
4、设置默认值
let [x, y = 'b'] = ['a', undefined]; // x='a', y='b'
5、提前json数据
let jsonData = {
id: 42,
status: "OK",
data: [867, 5309]
};
let { id, status, data: number } = jsonData;
三、字符串扩展
es6为字符串新增了遍历接口
现在字符串可以被for of遍历
for (let it of 'foo') {
console.log(it)
}
实用的新增方法
1、类似indexOf的方法
includes():返回布尔值,表示是否找到了参数字符串。
startsWith():返回布尔值,表示参数字符串是否在原字符串的头部。
endsWith():返回布尔值,表示参数字符串是否在原字符串的尾部。
2、新增的replaceAll()与replace的比较(参数1匹配项,参数2替换项)
区别在于参数1,当参数1为字符串时,replace替换第一个匹配项,
replaceAll替换全部。
当参数2为正则时,replace支持全局(/g)和非全局,replaceAll必须是全局,否则报错
3、at()参数为一个下标数字,支持负数
查询指定下标位置的字符
4、matchAll()
[...string.matchAll(regex)]
四、正则扩展
RegExp正则对象
var regex = new RegExp('xyz', 'i');
或
var regex = new RegExp(/xyz/i,'g');//es6支持覆盖修饰符
五、数值扩展
ES6 将全局方法parseInt()和parseFloat(),移植到Number对象上面
六、函数扩展
1、es6允许函数参数设置默认值
function log(x, y = 'World') {
console.log(x, y);
}
2、函数参数设置默认值与解构赋值的默认值
function foo({x, y = 5}) {
console.log(x, y);
}
foo({x: 1}) // 1 5
foo({x: 1, y: 2}) // 1 2
3、rest参数
使用(…变量名)的写法,存储额外参数,代替使用arguments对象
arguments是类数组对象,使用前需使用Array.from转化,而rest是真正的数组。
注:rest参数必须放到最后,否则报错
4、箭头函数
特点:
没有this、不能new(因为没有this)、没有arguments(可使用rest替代)
关于箭头函数的this:
其内部的this固定为定义时的上层作用域中的this,且不可变
5、尾调用、尾递归优化
在函数最后一项操作中仅return一个调用函数调用
可以避免保存调用帧,大大节约内存
function Fibonacci2 (n , ac1 = 1 , ac2 = 1) {
if( n <= 1 ) {return ac2};
return Fibonacci2 (n - 1, ac2, ac1 + ac2);
}
七、数组扩展
1、扩展运算符
(…)用于展开一个拥有遍历接口的对象
2、Array.from
将可遍历对象或类数组对象转化为数组
3、新增方法
1、Array.of()将参数组成一个数组
用于补全Array构造函数的不足(对不同数量参数的不同处理)
2、fill()实例方法,以指定字符填充数组,操作原数组
参数1替换字符,参数2起止位置,参数3结束位置(不包含)
3、find()、findIndex()实例方法
以一个回调函数为参数,返回满足条件的第一个字符或下标
4、keys()和values()实例方法
返回实例的键名和键值的遍历器,再配合for of遍历
5、entries()实例方法
返回实例的键值对的遍历器,键值对为数组形式
for (let index of ['a', 'b'].keys()) {
console.log(index);
}
// 0
// 1
for (let elem of ['a', 'b'].values()) {
console.log(elem);
}
// 'a'
// 'b'
5、includes()实例方法
类似indexOf,但更直观,返回true和false,且能检测NaN
八、对象的扩展
对象的遍历
1、for…in
for…in循环遍历对象自身的和继承的可枚举属性(不含 Symbol 属性)。
2、Object.keys(obj)
Object.keys返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含 Symbol 属性)的键名。
对象新增方法
1、Object.is()
相比传统比较方法
Object.is(+0, -0) // false
Object.is(NaN, NaN) // true
2、Object.assign()方法用于对象可枚举属性的合并(浅拷贝)
Object.assign(target, source1, source2);//后面的属性会覆盖前面的
3、__proto__属性
读取或设置当前对象的原型对象(prototype)
4、keys()和values()实例方法
返回实例的键名和键值的遍历器,再配合for of遍历
5、entries()实例方法
返回实例的键值对的遍历器,键值对为数组形式
九、运算符扩展
1、指数运算符()
23=8
2、链式判断符 (?.)
存在则调用,类似短路运算
3、NULL判断符(??)
对比(||),仅左边为NULL或undefined执行右边
十、新增数据类型
symbol
set
map
十一、promise
new Promise
一个异步解决方案,promise以一个函数为参数,该函数的参数是resolve, reject(由js提供),promise中包含异步操作
如果操作成功,我们调用resolve改变promise状态至fulfilled,否则调用reject至rejected
then
后续使用then方法对结果进行操作,then以两个回调函数为参数,一个处理成功,一个处理失败状态。回调函数的参数为前一个promise的返回值。
then返回一个新的promise对象,使得他可以链式调用。
catch
仅解决失败状态
finally
无论状态如何都执行
Promise.all()
将多个 Promise 实例,包装成一个新的 Promise 实例
const p = Promise.all([p1, p2, p3]);
1、只有p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled,此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数。
2、只要p1、p2、p3之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。
十二、async
十三、class
可以看作构造函数的另一种写法
同样使用new创建实例
1、constructor()
构造方法,类的默认方法,认返回实例对象(即this)
2、getter,setter
拦截某个属性的存取行为,prop为属性名
class MyClass {
constructor() {
// ...
}
get prop() {
return 'getter';
}
set prop(value) {
console.log('setter: '+value);
}
}
3、this
尽量使用箭头函数,保证this始终指向实例本身
4、静态方法
static关键字,定义不被继承的方法,而是通过类来调用
5、静态属性
同上
6、继承
extends关键字+super关键字
类似原型链继承
十四、模块化
核心是export和import
export可以多次导出,
也可以export default
import可以import *
也可以import { } 选择引入
十五、遍历
1、原生具备 Iterator 接口的数据结构
Array
Map
Set
String
TypedArray
函数的 arguments 对象
NodeList 对象