一、let和const
这块相对来说还是比较基础的,有了解学习
let
和const
定义变量的一些特点:不能重复定义、不存在变量提升、const
定义常量且需要给初始值等ES6的块级作用域、暂时性死区等
二、变量的结构赋值
按照ES6的一定模式,可以从数组和对象中提取值,对变量进行赋值,这就是解构
- 数组解构
let a = 1; let b = 2; let c = 3;
let [a,b,c] = [1,2,3];
解构不成功,则变量的值就是
undefined
解构赋值允许指定默认值
let foo[foo = true] = [];
解构不仅用于数组,还可以用于对象
对象的解构赋值是先找到同名属性,然后再付给对应的变量,真正赋值的是后者,不是前者
三、模版字符串
- 普通字符串
`In JavaScript '\n' is a line-feed.`
- 多行字符串
`In JavaScript this is
not legal.`
- 字符串中嵌入变量
var name = "Bob", time = "today";
`Hello ${name}, how are you ${time}?`;
// Hello Bob, how are you today?
四、数值的扩展
学习了一些API,比如
Number.isNaN()
(判断是不是数字)、Number.isFinite()
(判断是否有限)、Number.parseInt()
(取整)、Number.isInteger()
(判断是不是整数)等等学习了Math对象的扩展,比如
Math.trunc()
(去除小数)、Math.sign()
(判断数值正负)、Math.cbrt()
(计算立方根)、Math.floor()
(向下取整)等等
五、函数的扩展
函数的参数可以指定默认值
参数可以跟解构赋值默认值结合使用
默认值的参数不是尾参数,无法只省略那个参数
函数含有
length
属性,就是参数的个数,如果有默认值,则长度减去默认值个数,rest
参数也不会计入length属性函数的作用域、严格模式、
name
属性rest
参数的形式为(...变量名),用来捕获多函数多余的参数,搭配的变量是一个数组,将多余的变量放到数组中-
箭头函数
- 箭头函数就是用()=> 定义函数,一个参数不需要用括号,两个或者多个就需要用圆括号把参数放里面
- 箭头函数可以省略
return
- 返回值是对象则需要在对象外面加一个圆括号
- 可以跟架构赋值结合使用
- 不能
new
实例化,没有prototype
原型、没有arguments
对象 -
this
指向最外层为非箭头函数的那个对象 - 不能使用
yield
命令,则不能用作生成器函数
尾调优化和函数参数的尾逗号
六、数组的扩展
- ...扩展运算符,好比rest参数的逆运算
console.log(1,...[2,3,4,5]);
//1,2,3,4,5
可以用来合并数组,可以跟解构赋值结合使用
可以把字符串穿换成数组
任何具有
Iterator
接口的对象都可以使用扩展运算符转换为数组Array.from
可以把一个类数组对象转变为一个真正的数组Array.of
可以把一组值转变为数组还学习了
find
、findIndex
、fill
、includes
等entries
、keys
、等方法也学习了解了
七、对象的扩展
允许直接写入变量和函数作为对象的属性和方法,用于函数的返回值
Object.is
方法判断两个值是不是严格相等Object.assign
方法用于对象的合并,还可以实现一定程度的拷贝(不可枚举的属性不能拷贝,继承属性不能拷贝)还学习了
__proto__
、Object.setPrototypeOf()
、Object.getPrototypeOf()
、Object.keys()
、Object.values()
、Object.entriess()
等一些API
八、Set和Map数据结构
Set 是一个构造函数,可以用来生成Set数据结构,Set 的成员是唯一的,则可以用来进行数组的去重
学习到了 Set 身上的一些API,比如 add (添加)、size(长度)、delete(删除)、clear(清除)、has(是否包含)等
数组的 map 和 filter 方法也是可以用在 Set 身上
Map 本质上是键值对的集合,它身上也是有很多的 API ,也进行了学习了解
对一个键值进行两次赋值,则后面的会覆盖前面的
const map = new Map();
map.set(1,'a').set(1,'b');
map.get(1); //'b'
- 可以进行Map和数组、数组、JSON 之间的转化
九、Iterator和for...of
Iterator
是个遍历器,具有next
方法,调用一次,指针指向他内部的下一个数据结构,不断调用,直到结束默认的接口部署在数据结构的
Symbol.iterator
属性上,也就是说有这个属性,那么就是可以遍历的扩展运算符(...)会默认调用
iterator
接口具有这个接口的就是可以遍历的,就可以使用 for...of 进行遍历
for...of 可以获得数组的键值,for...in 获得键名(索引)
十、Symbol
Symbol 是一种新的数据类型,表示独一无二的值
Symbol(),无论括号里面有没有参数,这两个值都不相等
Symbol.for(),括号里参数相同,则就是同一个值,就是相等的
Symbol.keyfor(),则表示一个已经登记的 Symbol 类型值的 key
十一、Promise
promise是一种异步编程解决方案,里面有未来会结束的事件,有三种状态,pending(进行中)、fulfilled(成功)、rejected(失败)
promise 对象是一个构造函数
var promise = new Promise(function(res,rej)){
if(/异步操作成功/){
resolve(val)
}else{
rej(reason)
}
}
promise实例生成后,可以用 then 方法来分别制定成功和失败的回调函数
then方法可以实现链式调用,可以将上一步结束的值作为参数传给下一个 then
promise.all()
、promise.race()
也纳入了学习内容中并尝试结合一些资料和教程,实现了一个自己的 promise(部分功能)
//依据 promise a+ 规范
function MyPromise(exector) {
var self = this;
self.state = 'pending';
self.resolveValue = null; //存储成功的返回值用作then执行的时候的参数
self.rejectValue = null; //存储失败的返回值用作then执行的时候的参数
self.ResolveCallBackList = []; //存储then里面的回调函数
self.RejectCallBackList = [];
//成功执行
function resolve(value) {
if (self.state === 'pending') {
self.state = 'fulfilled';
self.resolveValue = value;
self.ResolveCallBackList.forEach(function(ele) { //异步操作完成到执行这个方法的时候从数组里拿出来执行
ele();
})
}
};
//失败执行
function reject(reason) {
if (self.state === 'pending') {
self.state = 'rejected';
self.rejectValue = reason;
self.RejectCallBackList.forEach(function(ele) { //异步操作完成到执行这个方法的时候从数组里拿出来执行
ele();
})
}
}
//异常处理
try {
exector(resolve, reject); //同步执行
} catch (e) {
reject(e); //接受同步执行报出的错误
}
}
//处理各种返回值
function ResolutionReturnPromise(nextPromise, returnValue, res, rej) {
if (returnValue instanceof MyPromise) { //返回值是一个Promise对象
returnValue.then(function(val) {
res(val) //给返回值是promise对象里面的成功的 下一个注册then方法(外部调用)
}, function(reason) {
rej(reason) //给返回值是promise对象里面的失败的 下一个注册then方法(外部调用)
})
} else {
res(returnValue)
}
}
//原型上的then方法
MyPromise.prototype.then = function(onFulfilled, onRejected) {
var self = this;
//链式调用空then处理
if (!onFulfilled) { //如果then的成功处理函数不存在,即为空的then,直接return传入的值
onFulfilled = function(val) {
return val
}
}
if (!onRejected) { //如果then的失败处理函数不存在,即为空的then,如果有错误抛出来,则传递给下一个
onRejected = function(reason) {
throw new Error(reason)
}
}
var nextPromise = new MyPromise(function(res, rej) {
//进行异步操作的时候这一块的状态还是pending,不会进去的
if (self.state === 'fulfilled') {
setTimeout(function() { //没有操作微任务的权限,则用setTimeout来模拟
try {
var nextResolveValue = onFulfilled(self.resolveValue);
// res(nextResolveValue);
ResolutionReturnPromise(nextPromise, nextResolveValue, res, rej) //解决所有类型的返回值
} catch (e) {
rej(e)
}
}, 0)
};
if (self.state === 'rejected') {
setTimeout(function() {
try {
var nextRejectValue = onRejected(self.rejectValue);
// res(nextRejectValue);
ResolutionReturnPromise(nextPromise, nextRejectValue, res, rej)
} catch (e) {
rej(e)
}
}, 0)
}
if (self.state === 'pending') {
setTimeout(function() {
try {
self.ResolveCallBackList.push(function() {
var nextResolveValue = onFulfilled(self.resolveValue);
// res(nextResolveValue);
ResolutionReturnPromise(nextPromise, nextResolveValue, res, rej)
})
} catch (e) {
rej(e)
}
}, 0);
setTimeout(function() {
try {
self.RejectCallBackList.push(function() {
var nextRejectValue = onRejected(self.rejectValue);
// res(nextRejectValue);
ResolutionReturnPromise(nextPromise, nextRejectValue, res, rej)
})
} catch (e) {
rej(e)
}
}, 0)
}
})
return nextPromise; //实现链式操作,把上一步then执行完返回的一个新的promise给return出来
}
十二、class
class是一个类,他的数据类型是函数,本身就指向构造函数,也需要用 new 关键字来使用
里面有原型方法、静态方法、私有的属性等,不存在变量提升
学习 class 的时候要结合 js 的原型和原型链一起来学习,类的所有实例共享一个原型对象
类的方法内部有this默认指向类的实例,单独使用方法会报错
学习了解了 class 的取值函数和存执函数,函数名为变量时候要使用方括号
class 的继承使用 extends 关键字
super 当函数使用时候,代表父类的构造函数,子类构造函数必须执行一次 super 函数
super 虽然嗲表了父类的构造函数,但是 this 指向子类
super 只能在子类的构造函数中使用,在其他地方就会报错
super 作为对象使用时候,在普通方法指向父类原型对象,在静态方法指向父类
super 指向父类的原型对象,所以定义在父类实例上面的方法是不能通过 super 调用的
十二、Generator函数
是个生成器函数,相比于普通函数,它在 function 关键字后面加了一个 * 号,内部用的 yield 表达式
调用这个函数后,返回的是一个遍历器对象,则可以使用 next 方法,next 方法可以传值
也可以使用 for...of 循环,循环 yield 表达是后面的值,不会遍历出 return 的值
十三、async函数
async
就是Generator
函数的语法糖就是把
Generator
函数的星号替换成async
,把yeild
替换成await
而已async
函数相对于Generator
函数的改进提现在如下
- 内置执行器,也就是说,
async
函数的执行就跟普通函数一样就行了 - 语义化更好,
async
跟await
相比于yield
跟星号,更加语义化 - 广泛的适用性,
await
侯敏可以使promise
对象也可以是原始类型的数值 - 返回值是
promise
,比Generator
函数返回的Iterator
更加方便,可以用then
方法指定下一步的操作
- async有多种使用形式
//函数声明
async function foo(){}
//函数表达式
const foo = async function (){}
//对象的方法
let obj = {async foo(){}}
obj.foo().then(.....)
//class的写法
//箭头函数
const foo = async()=>{};
async
函数返回一个Promise
对象内部
return
返回出来的会成为then
方法回调函数的参数
async function f (){
return 'hello world';
}
f().then(v=>console.log(v));
//'hello world'
await命令正常情况下
await
后面返回的是一个promise对象,返回对象的结果,如果不是promise
对象,则直接返回那个值await
后面的promise
对象要是变成rejecte
状态,则会被后面的catch
的回调函数接收到任何一个
await
后面的Promise
对象变为reject
状态,那么整个async函数会中断执行
async function f() {
await Promise.reject('出错了');
await Promise.resolve('hello world'); // 不会执行
}
- 要是希望不会中断函数执行,则把它放在
try catch
里面,或者就是在await
后面的promise对象后面加一个catch
来捕获错误,await
只能放在await
函数内部,否则会报错
十四、prox和reflect
简单的了解了一下这部分
跟
Object.defineProperty
结合对比学习了一下