1.let、const
let
1)let声明的变量只在代码块内有效(块级作用域),for循环适合用
2)let不允许在相同作用域内,重复声明同一个变量。
3)不存在变量提升
4)暂时性死区(在代码块内,使用let命令声明变量之前,该变量都是不可用的)
const
1)变量指向的那个内存地址所保存的数据不得改动,即常量值不可变,对象的值可变
es6声明属性六种方法
var
function
let
const
import
class
顶层对象
顶层对象,在浏览器环境指的是window对象,在 Node 指的是global对象
es5 顶层对象的属性与全局变量是等价的
es6中let命令、const命令、class命令声明的全局变量,不属于顶层对象的属性
// 2.变量的解构赋值
/*
数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。
*/
// 3.字符串的扩展
/*
模板字符串
*/
// 4.字符串的新增方法
/*
includes(), startsWith(), endsWith('world', 6) 返回布尔值
repeat() 返回一个新字符串,表示将原字符串重复n次
padStart(5, 'ab')用于头部补全,padEnd()用于尾部补全
trim()一致,trimStart()消除字符串头部的空格,trimEnd()消除尾部的空格
'aabbcc'.replaceAll('b', '_')
*/
// 5.数值的扩展
/*
Number.isFinite()和Number.isNaN()
Number.parseInt(), Number.parseFloat()
Number.isInteger()
Math.trunc() 去除一个数的小数部分,返回整数部分
*/
// 6.函数的扩展
/*
函数的参数指定默认值
rest 参数之后不能再有其他参数(即只能是最后一个参数)
function add(...values) {} values是个数组
箭头函数
箭头函数没有自己的this对象
对于普通函数来说,内部的this指向函数运行时所在的对象,但是这一点对箭头函数不成立。
它没有自己的this对象,内部的this就是定义时上层作用域中的this。
也就是说,箭头函数内部的this指向是固定的,相比之下,普通函数的this指向是可变的。
不使用场合
定义对象的方法,对象不构成单独的作用域
需要动态this的时候
*/
// 6.数组的扩展
/*
扩展运算符(...)
rest参数的逆运算,将一个数组变为参数序列
扩展运算符的应用
复制数组 a2=[...a1]
合并数组 [...a1,...a2]
Map 和 Set 结构,Generator 函数
扩展运算符内部调用的是数据结构的 Iterator 接口,因此只要具有 Iterator 接口的对象,都可以使用扩展运算符
Array.from()
Array.from方法用于将两类对象转为真正的数组:类似数组的对象(array-like object)和可遍历(iterable)的对象(包括 ES6 新增的数据结构 Set 和 Map)
*/
// 7.对象的方法
/*
Object.is()
它用来比较两个值是否严格相等,与严格比较运算符(===)的行为基本一致。
Object.assign(target, source1, source2)
用于对象的合并
浅拷贝,而不是深拷贝
可枚举属性 Object.defineProperty enumerable
Object.keys()
返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键名
Object.values()
返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键值
Object.entries()
返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键值对数组
*/
// 8.Promise
/*
异步编程解决方案
所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果
是个构造函数,new一个实例
let p = new Promise(function(resolve,reject){
// 同步调用
console.log('111)
// 保存异步结果
resolve(value) // 异步操作成功时调用,保留异步成功的结果value
reject(error) // 在异步操作失败时调用,保留异步失败的结果error
})
let p1 = p.then(function success(value){},function error(error){})
有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)
状态发生改变会触发then()里的响应函数处理后续步骤
一旦状态改变,就不会再变,任何时候都可以得到这个结果
从pending变为fulfilled 或 从pending变为rejected
Promise.prototype.then()
then方法返回的是一个新的Promise实例
Promise.prototype.catch()
Promise 对象的错误具有“冒泡”性质,会一直向后传递,直到被捕获为止。也就是说,错误总是会被下一个catch语句捕获。
Promise.prototype.finally()
用于指定不管 Promise 对象最后状态如何,都会执行的操作
promise
.then(result => {···})
.catch(error => {···})
.finally(() => {···});
Promise.all([p1, p2, p3]) 要全成功才成功
Promise.all中的执行的顺序其实应该是并行的
将多个 Promise 实例,包装成一个新的 Promise 实例
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的回调函数
Promise.race()
将多个 Promise 实例,包装成一个新的 Promise 实例
只要p1、p2、p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p的回调函数(返回值为最快完成的那个promise结果)
Promise.allSettled()
用来确定一组异步操作是否都结束了(不管成功或失败)
Promise.any()
等到所有参数 Promise 变成rejected状态才会结束。
有一个变成fulfilled,Promise.any()返回的 Promise 对象就变成fulfilled。
Promise.resolve()、Promise.reject()
将现有对象转为 Promise 对象
*/
// 8.Generator 函数
/*
异步编程解决方案
一个状态机,封装了多个内部状态
Generator 函数返回的遍历器对象,只有调用next方法才会遍历下一个内部状态,所以其实提供了一种可以暂停执行的函数。yield表达式就是暂停标志。
function* helloWorldGenerator() {
yield 'hello';
yield 'world';
return 'ending';
}
let hw = helloWorldGenerator() // 遍历器对象
hw.next()
yield表达式与return语句既有相似之处,也有区别。
相似之处在于,都能返回紧跟在语句后面的那个表达式的值
区别在于每次遇到yield,函数暂停执行,下一次再从该位置继续向后执行,而return语句不具备位置记忆的功能(return只能执行一次)
ES6 诞生以前,异步编程的方法,大概有下面四种。
回调函数
事件监听
发布/订阅
Promise 对象 - 只是回调函数的改进,使用then方法以后,异步任务的两段执行看得更清楚了
*/
// 8.async 函数 await
/*
异步编程解决方案
async 函数就是 Generator 函数的语法糖
写法上 async函数就是将 Generator 函数的星号(*)替换成async,将yield替换成await,仅此而已
await 也是状态机,只有await后的代码执行完成后才能向后执行,
await后是个promise对象,返回该对象的结果
错误捕获
async函数返回一个 Promise 对象
必须等到内部所有await命令后面的 Promise 对象执行完,才会发生状态改变,除非遇到return语句或者抛出错误。
任何一个await语句后面的 Promise 对象变为reject状态,那么整个async函数都会中断执行。
*/
// 9.Class
/*
ES6 的class可以看作只是一个语法糖,ES5 构造函数 + prototype
class Person{
// 构造方法
constructor(a,b,c){
// this关键字则代表实例对象
this.a = a
this.b = b
this.c = c
}
// 类的所有方法都定义在类的prototype属性上面
print(){
console.log("print")
}
}
let one = new Person('a','b','c')
get和set关键字,对某个属性设置存值函数和取值函数,拦截该属性的存取行为。
this它默认指向类的实例,this一直指向类的实例的方法
constructor方法中绑定this
this.fn = this.fn.bind(this);
箭头函数
this.fn = ()=>{}
static(静态方法)
在一个方法前,加上static关键字,就表示该方法不会被实例继承,而是直接通过类来调用,这就称为“静态方法”。
继承
class A extends B{
constructor(a,b,c,d){
// 调用父类的constructor(x, y)
// super在这里表示父类的构造函数,用来新建一个父类的实例对象。
super(a,b)
this.c = c
this.b = b
}
}
子类自己的this对象,必须先通过父类的构造函数完成塑造,得到与父类同样的实例属性和方法,然后再对其进行加工,添加子类自己的实例属性和方法。如果不调用super()方法,子类就得不到自己的this对象。
ES5 的继承机制,是先创造一个独立的子类的实例对象,然后再将父类的方法添加到这个对象上面,即“实例在前,继承在后”。ES6 的继承机制,则是先将父类的属性和方法,加到一个空的对象上面,然后再将该对象作为子类的实例,即“继承在前,实例在后”。这就是为什么 ES6 的继承必须先调用super()方法,因为这一步会生成一个继承父类的this对象,没有这一步就无法继承父类。
*/