# 1.声明变量的let和const
在ES6之前,声明变量用var。
在ES6的时候就多了一个叫let,用来声明变量,一个叫const,用来声明常量。
let:可以说, let是更完美的var
let和var的区别:
①、let声明的变量具有块级作用域,而var声明的没有
举个简单的列子:
for(var i = 0; i < 5; i++){}
console.log(i);
2
在for循环中,用var声明的变量在for循环结束后还能在全局的作用域链上能访问到
但是用let声明的变量只在for循环里有效,在for循环以外的作用域都访问不了
②、不存在变量提升
var命令会发生”变量提升“现象,即变量可以在声明之前使用,值为undefined。
let所声明的变量一定要在声明后使用,否则报错ReferenceError(引用错误)。
③、暂时性死区
let命令,它所声明的变量就“绑定”(binding)这个区域,不再受外部的影响。
简单来说,在代码块内,使用let命令声明变量之前,该变量都是不可用的。
if (true) {
// TDZ开始
tmp = 'abc'; // ReferenceError
console.log(tmp); // ReferenceError
let tmp; // TDZ结束
console.log(tmp); // undefined
tmp = 123;
console.log(tmp); // 123
}
2
3
4
5
6
7
8
9
10
11
④、不允许重复声明
var是允许在同一作用域里重复声明同一个变量
而let不允许在相同作用域内,重复声明同一个变量
⑤、不属于顶层对象
用var声明的变量属于顶层对象,在浏览器中可以window访问
let声明的全局变量不是全局对象的属性。不可以通过window访问,
用var命令和function命令属于window的属性
而let、const、class都不属于
const:
const声明一个只读的常量。一旦声明,常量的值就不能改变。
const实际上保证的,是变量指向的那个内存地址所保存的数据不得改动。对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,因此等同于常量。
但对于复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指向实际数据的指针,const只能保证这个指针是固定的(即总是指向另一个固定的地址),至于它指向的数据结构是不是可变的,就完全不能控制了。
# 2.函数的扩展
①、箭头函数
优点:
(1)、函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。
(2)、写法更加简洁
缺点:
(1)、不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误。
(2)、不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。
(3)、不可以使用yield命令,因此箭头函数不能用作 Generator 函数。
②、函数默认值
直接为函数的参数指定默认值
function Point(x = 0, y = 0) {}
③、rest参数
用于获取函数的多余参数,这样就不需要使用arguments对象了。
rest 参数搭配的变量是一个数组,该变量将多余的参数放入数组中。
function add(...values) {
let sum = 0;
for (var val of values) {
sum += val;
}
return sum;
}
add(2, 5, 3) // 10
2
3
4
5
6
7
8
# 3.数组的扩展
①、扩展运算符
扩展运算符(spread)是三个点(...)。它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列。
console.log(...[1, 2, 3])
// 1 2 3
2
②、Array.from()
Array.from方法用于将类似数组的对象和可遍历的对象转为真正的数组对象。
let arrayLike = {
'0': 'a', '1': 'b', '2': 'c', length: 3
};
// ES5的写法
var arr1 = [].slice.call(arrayLike); // ['a', 'b', 'c']
// ES6的写法
let arr2 = Array.from(arrayLike); // ['a', 'b', 'c']
2
3
4
5
6
7
8
9
③、创建数组的方式
1、 let arr = new Array();
2、 let arr = [1, 4, 5];
3、 let arr = Array.of(3, 11, 8) // es6
4、 let arr = Array.from({length : 3}) // 数组初始值为undefined,Array.from还可以接受map映射,
let arr = let abc = Array.from({length : 3}, (item, index) => index)
2
3
4
5
④、其他方法
find() 、findIndex() 找第一个元素的值、索引
keys() 、values() 、entries() 键、值、键值对的遍历
flat() 数组降维
# 4.对象的扩展
Object.is() 相当于全等符(===),不同之处只有两个:一是+0不等于-0,二是NaN等于自身
Object.assign 合并对象(一层深拷贝)
Object.keys() 、Object.values() 、Object.entire() 分别遍历 键、值、键值对
利用 Object.setPrototypeOf()、Object.getPrototypeOf() 分别对对象的隐式原型进行读写
Object.fromEntries() 将一个键值对数组转为对象
# 5.Promise介绍
Promise 对象是异步编程的一种解决方案,最早由社区提出。
Promises/A+ 规范是 JavaScript Promise 的标准,规定了一个 Promise 所必须具有的特性。
Promise对象有以下两个特点。
一、对象的状态不受外界影响。
Promise对象代表一个异步操作,
有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。
只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。
二、一旦状态改变,就不会再变,任何时候都可以得到这个结果。
Promise对象的状态改变,只有两种可能:
从pending变为fulfilled和从pending变为rejected。
只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)。
Promise的出现:解决传统的回调地狱函数
三、终止Promise
自己的思路:在then方法里,throw出一个new error,在随后catch方法,返回一个新的Promise对象,处于pending状态
myPromise.then(suc => {
throw new Error('test')
}, reject => {
}).catch(){
return new Promise((resolve, reject) => {
})
}
2
3
4
5
6
7
8
9
10
Promise.prototype.then()
作用是为 Promise 实例添加状态改变时的回调函数
then方法的第一个参数是 resolved 状态的回调函数,第二个参数(可选)是 rejected 状态的回调函数。
then方法返回的是一个新的Promise实例,因此可以采用链式写法
Promise.prototype.catch()
是.then(null, rejection) 或.then(undefined, rejection) 的别名,用于指定发生错误时的回调函数
一般来说,不要在then方法里面定义 Reject 状态的回调函数(即then的第二个参数),总是使用catch方法。
catch方法返回的还是一个 Promise 对象
// good
promise
.then(function(data) { //cb
// success
})
.catch(function(err) {
// error
});
2
3
4
5
6
7
8
Promise.prototype.finally() [ES2018]
finally方法用于指定不管 Promise 对象最后状态如何,都会执行的操作。
promise
.then(result => {···})
.catch(error => {···})
.finally(() => {···});
2
3
4
不管promise最后的状态,在执行完then或catch指定的回调函数以后,都会执行finally方法指定的回调函数。
Promise.all()
用于将多个 Promise 实例,包装成一个新的 Promise 实例
如果不是Promise实例,就会调用下面Promise.resolve方法
const p = Promise.all([p1, p2, p3]);
// 只有p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled,
// 此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数。
// 只要p1、p2、p3之中有一个被rejected,p的状态就变成rejected,
// 此时第一个被reject的实例的返回值,会传递给p的回调函数。
2
3
4
5
6
Promise.race()
同样是将多个 Promise 实例,包装成一个新的 Promise 实例
如果不是Promise实例,就会调用下面Promise.resolve方法
const p = Promise.all([p1, p2, p3]);
// 只要p1、p2、p3之中有一个实例率先改变状态,p的状态就跟着改变。
// 那个率先改变的 Promise 实例的返回值,就传递给p的回调函数。
2
3
# 6.async/await
async 可以说是在generator的基础上进行改进
generator函数的执行要通过next()方法,除此之外还可以依靠co模块,而async函数像普通函数一样执行
async函数的返回值是 Promise 对象,这比 Generator 函数的返回值是 Iterator 对象方便多了
async的语法比promise和generator都简单
# 其他简明概要
①、模板字符串
②、变量解构赋值
③、Iterator 接口 和 for of循环
④、symbol
原始数据类型Symbol
凡是属性名属于 Symbol 类型,就都是独一无二的,可以保证不会与其他属性名产生冲突。
⑤、Set 和 Map 数据结构
Set:类似于数组,但是成员的值都是唯一的,没有重复的值。
Map::类似于对象,也是键值对的集合,
但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。
也就是说,Object 结构提供了“字符串—值”的对应,Map 结构提供了“值—值”的对应,是一种更完善的 Hash 结构实现。
Set方法:
add(value):添加成员 结余接收具有iterable接口数据结构作为参数
has(value):返回一个布尔值,表示该值是否含有该成员。
delete(value):删除某个值,返回一个布尔值,表示删除是否成功。
clear():清除所有成员,没有返回值。
size():返回实例的成员总数
Map 相比Set多了set和get方法
set(key, value)
get(key)
少了add方法
WeakSet
1、WeakSet 的成员只能是对象
2、WeakSet 中的对象都是弱引用,即垃圾回收机制不考虑 WeakSet 对该对象的引用
WeakMap
1、只接受对象作为键名
⑥、模块化import 和 export
⑦、class以及extend