Es6语法
1.let和const声明变量
当时用var进行声明变量时,会出现变量提升的问题:
console.log(b); //undefined var b = 100 arr = []; for (var i = 0; i < 10; i++) { arr[i] = function () { return i } } console.log(arr); // [?, ?, ?, ?, ?, ?, ?, ?, ?, ?] 10个函数的数组 console.log(arr[5]()); // 取到的值是10,正常应该是5才对。 这就是变量提升! 为什么?因为在执行var进行变量声明时出来了变量提升。i被提升到全局作用域中,i就被赋值为循环后的最后结果10。 怎么解决?使用let去声明就不会出现这个问题 1.let 声明变量: 1.他是一个变量声明方法 2.是一个块级作用域,相当于类中的类变量,只能被类中的方法和对象使用。 3.let 声明的变量不能重复情况,不能被覆盖 报错 console.log(b); //打印报错 let b = 100 let a = 10 let a = 100 conlost.log(a) // 报错a重复出现 2.const 变量声明: 1.是一个变量的方法 2.是块级作用域 3.不能重复声明 4.声明后不能修改 const a = 100 a = 1000 // 无法重新赋值,报错 const p = { name:'xxx', age : '18' } // 不能直接修改p这个对象,但是可以修改p内部的值 p.age = 20
2.模板字符串的语法
结果:
xxx
3.Es6的函数与Es5的区别
1.带有参数的模板值函数
es5写法
function add(a, b) {
a = a || 10, // 使用双管道符 或的方式进行声明默认值
b = b || 10
return a+b
}
es6写法
function add(a = 10, b = 20) { // 带默认参数
return a + b
}
2.默认表达式
es6 默认知可以为一个函数对象
function add(a,b=date(5)){ // b默认值需要等到b函数执行完毕后
return a+b
}
function date(val){
return 5 + val
}
4.运算符
1.剩余运算符。
可以将在函数中剩余的参数进行获取
es5:
function pick(object) {
let res = Object.create(null) // 创建一个没有任何方法的对象
for (let i = 1; i < arguments.length; i++) {
// arguments 对象: 是一个对应于传递给函数的参数的类数组对象
res[arguments[i]] = object[arguments[i]] // 进行对传入的对象进行赋值
}
return res
}
//创建一个对象
let book = {
title: '1231',
author: "65465",
year: 2019,
}
let bookdata = pick(book, 'title', 'author',"year") // 将值传入进行取
console.log(bookdata) //
es6:
剩余运算符写法 使用...key(key可以随便那个定义都可以)
function pick(object, ...key) { // ...key 返回一个数组
console.log(key) // ...key 接受到 传入'title', 'author', "year"3个名称
let res = Object.create(null)
for (let i = 0; i < key.length; i++) {
res[key[i]] = object[key[i]]
}
return res
}
// 声明对象
let book = {
title: '1231',
author: "65465",
year: 2019,
}
let bookdata = pick(book, 'title', 'author', "year")
console.log(bookdata)
// 剩余运算符相当于,将除了固定值以外的内容全部接受了,返回一个数组(与python中的args和kwargs相同)
2.扩展运算符
将数组进行分割为一个一个的
es5写法
const arr = [11,22,33,44,566,778979,9879] //数组
//获取 数组中最大的值
console.log(Math.max.apply(null,arr))
const add = Math.max(11,22,33,45646,4654,6,) // 将值传入进行获取最大值
console.log(add)
es6:
// 直接将数组中的每一个值进行分离传入max函数中进行对比取出来最大的值
console.log(Math.max(...arr))
而这个扩展运算符相当于 *args 与 **kwargs 差不多
5.箭头函数
es6中的箭头函数取代了匿名函数
取代function(){} 等价于 ()=>{} 匿名函数
例如:
let add = function (a, b) {
return a + b
}
console.log(add(10, 20)) // 获取结果就是30
es6的方式(多个参数的情况下) 箭头函数相当于 将function给替代为 =>
let add = (a,b) => {
return a + b
}
console.log(add(10,20)) // 获取的结构 也是30
另一种写法
let add = (a,b) = > a+b
箭头函数中参数问题:
带一个参数:
let add = (a)=>{
return a+10
}
各种写法
let add = val =>val; //这中情况相当于
let add = val => (val+5) //这中情况相当于
let add = val => { return val + 5 } //这中情况相当于
没有参数的情况下
// 没有参数的情况下 前面的小括号必须写
let add = () =>{return 'hahahh'}
console.log(add())
箭头函数返回对象
let add = () =>{
return
{id:1,
name:'123'
}
}
简写:
let add = id =>({id:1,'name':1233})
// 关于闭包函数
es5闭包:
let fn = (function(){
return function(){
return 123 // 将123 参数返回给了function匿名函数
}
})() // 第一层函数执行,获取到的第二层的function函数(没有执行) 需要执行
fn(); // 执行内层的函数
es6箭头函数闭包
let fn = (() => {
return () => {
return123
}
}) (); // 第一层函数执行,获取到的第二层的function函数(没有执行) 需要执行
fn(); // 执行内层的函数
6.箭头函数的this指向问题
es5的this指向
// es5 中的this指向:取决于调用该函数的上下文对象
let pa = {
id : 10,
init:function(){
// 添加一个click事件
//document.addEventListener 给文档设置一个点击事件,当点击文档中的任何一个位置,就会出发内部函数
document.addEventListener('click',function(){
console.log(this); // this指向了 document文档对象
this.doSomeThings(event.type) // event.type打印 绑定类型 传入函数doSomeThings
console.log(event.type) // 类型打印的时 click点击事件
}.bind(this),false) //设置bind方法 将this指向 pa 对象 //就会执行doSomeThings函数
},
doSomeThings:function(type){
console.log(`事件类型${type},事件id${this.id}`)
}
}
pa.init()
es6中的this执行
//es6 解决this指向问题 // 使用=> 就会找上层的作用域
// 箭头函数之后没有this指向,通过查找作用域进行找
// 一但使用箭头函数,当前有没有作用域,就找上层的作用域
// 3层作用域 this
let pa = {
id : 10,
// 2级作用域 this
init:function(){
// 1级作用域 this
document.addEventListener('click',(event)=>{
// console.log(this);
this.doSomeThings(event.type)
// console.log(event.type)
},false)
},
doSomeThings:function(type){
console.log(`事件类型${type},事件id${this.id}`)
}
}
pa.init()
// 怎么查找作用域
// 在 document.addEventListener方法定义的内部是一个作用域
// 这个作用域上层指向了 init:function init变量
// init 变量的上层作用域 指向了对象pa 所以 this指向pa对象
// 假设 int:function 定义为箭头函数 => 那么相当于 init没有作用域,就会找到pa对象的作用域
// 在找到window 作用域练 最外层
使用箭头函数的注意事项:
1.使用箭头函数就会内部就没有 arguments 方法,因为使用箭头函数就没有作用域链,就会指向weindow
2.不能使用new进行创建箭头对象,因为箭头对象没有作用域
7. 解构
// 解耦语法是一种对运算的一种扩展
// 主要针对 数组和对象操作
// 优点:优化代码和易读性
1.针对完整的对象
let info = {
type: 'id',
name: ' askjh'
}
es5获取对象中的值
let type = info.type
let name = info.name
es6解构语法
let { type, name } = info
2.针对不完全解构 可以忽略某些属性
let obj = {
a: {
name: '张三'
}, // 对象
b: [], // 数组
c: 'hello world'
}
let {a} = obj // 获取obj对象中的a对象
也可以使用剩余运算符进行获取剩下的值
let {a,...key} = obj
key : {b: Array(0), c: 'hello world'}
3.使用解构进行默认值赋值
let {a,b=30} = {a:40} // 设置b的默认值为30 a赋值为40
进行数组的复制
let arr = [1,2,3]
let [a,b,c] = arr
结果:123
嵌套结构:
// 相当于python 中的 a,b = 1,3 但是需要根据对应参数的形式获取值
let [n,[d],e] = [1,[2],3] //1 2 3
8.对象与数组的扩展
1.对象的扩展
关于写入:
const name=12, age=12
es5写法
const pe = {
name:name,
age:age
//写入函数
sayName:function(){}
}
函数中的参数:
function add(x,y){
return{x:x,y:y}
}
es6写法
const pe = {
name,
age
//写入函数
sayName(){} // 只写省略了function
}
function add(x,y){
return{x,y}
}
es6的其他:
set 与 get 方法
当直接执行get 方法就会根据默认值执行 就会直接执行get
当执行set是会优先执行set方法,在执行get方法
let add= {
wheel:4 ,
// 在调用 get方法执行时,就会先执行这个方法进行判断
set(val){
if (val < this.wheel){
throw new Error('数量太少') // throw 抛出异常
}
},
get(){ // 等待set方法执行完毕后才会执行
return this.wheel
}
}
caet.set(3) // 对方法传入3时,在执行 get 就会获取set值的判断结果
console.log(caet.get()) // 如果不对set传入值,那么默认就会参数就是wheel
es6属性表达式
const obj = {}
obj.isshow = true // 对obj对象进行赋值
const name = 'a'
obj[name+'bc'] = 123 // 将name变量 和 bc 进行拼接进行写入对象中
结果:{isshow: true, abc: 123}
写入函数对象
obj['f'+ 'cc'] = function(){
console.log(this);
}
结果:{isshow: true, abc: 123, fcc: ?}
对象的其他方法2
is() 相当于 === 比较与两个值是否严格相同
console.log(NaN === NaN); // 不严谨 false
console.log(Object.is(NaN,NaN)); // true
assign() 对象的合并 属于浅拷贝
let t={}
let b={a:2}
Object.assign(t,b) // 将b中的值写入到t对象中 获取一个新的对象
console.log(t) // {a: 10}
2.数组扩展
数组的方法:from 与 of
from 可以 将伪数组转换为真正的数组
数组的 of 将一组的值转换为数组 任意的数据类型转换为数组
es5:
function add(){
arguments //是一个伪数组对象
let arr = [].slice.call(arguments)
console.log(arr) // es5方法直接转换为一个真的数组
}
es6 中的from
function add(){
arguments //是一个伪数组对象
let arr = Array.from(arguments); //直接调用form方法转换
console.log(arr)
}
from的第二个参数:
let lis = document.querySelectorAll('li') // 获取全部的li标签
// 第二个参数是一个回掉函数处理转换的数组中的元素
// ele 接受每一个 li标签 在获取ele.textContent 标签中的文本
let list = Array.from(lis, (ele) => { return ele.textContent })
变成数组并且获取了li标签中的值
es6中的of
console.log(Array.of(3,1,2,4,5,6,7,88,9)); //[3, 1, 2, 4, 5, 6, 7, 88, 9]
es6数组中的copywithin()方法
复制替换将数组中的值进行替换 返回当前的数组
let a = [1, 2, 3, 4, 5, 6].copyWithin(0, 3) // 原结果[1,2,3,4,5,6]
将0-3的数替为4-5 因为顾前不顾后
console.log(a); // [4,5,6,4,5,6]
es6数组中的findindex()方法 find查找数值
find查找数值:获取数值 第一个符合条件的
findindex()方法:获取数值的下标索引 第一个符合条件的
[1, 2, -103, 4, 5, -10, 7].find((n) => { // n就是遍历数组的每一个值
return n < 0
}
[1, 2, -103, 4, 5, -10, 7].findindex((n) => { // n就是遍历数组的每一个值的下标
return n < 0
}
es6数组的
entries(对键值对遍历) keys(对键的遍历) values(对值的遍历) 返回一个遍历起 可以使用for ... of 进行遍历
与python中的items keys values 相同
key 取索引
let a = [1, 2, 3, 4, "a", 6].keys() // a是一个遍历器
console.log(a); // 获取的结构 就是一个遍历器Array Iterator
可以使用for ... of进行遍历
for (let index of a) {
console.log(index)
}
value取值
let b = [1, 2, 3, 4, "a", 6].values()
for (let index of b) {
console.log(index)
}
entries() 取值和索引
let c = [1, 2, 3, 4, "a", 6].entries()
for (let [key, val] of c) {
console.log('这是键', key) // 获取索引
console.log('这是值', val) // 获取值
}
includes 返回一个bool值 表示一个数组是否包含这个值
console.log([1,2,3,4].includes(2)); // true
console.log([1,2,3,4].includes(10)); //false
9.es6新数据类型
新的数据类型
// 原始数据 symbol ,表示他他是一个独一无二的值
const name = Symbol('name') // 内存地址不一样
const name2 = Symbol('name') // 独一无二的一个值
虽然值相同,但是内存地址不同,独一无二的
console.log(name === name2); //false
symbol可以设置私有属性
注意:
//用来定义对象的私有变量// 可以设置对象的私有的属性
//如果使用symbol声明的变量 在取值时 一定要用[]取值
// 无法进行for遍历
let s1 = Symbol('name')
let obj = {
[s1] : '123' // 存值
}
obj[s1] //取值
//两种方式 symbol声明的属性名(作为对象的key)
Object.getOwnPropertyDescriptor(obj)[0] // 获取值
Reflect.ownKeys(obj)
1.es6的set集合类型
先创建一个set的类型
let set = new Set() //打印后获取的结果是:Set(0) {size: 0} size表示集合的长度
//set 表示一个无重复值的有序列表 不能重复 无法被释放的类型
set.add(值) // 可以添加数值 集合 对象 字符串 布尔值
set.delete(值) // 删除
set.has(值) // 查看当前值是否存在 返回flase true
set.size() // 访问集合的长度
将set类型转为数组
let set2 = new Set([1,2,3,4,4,5,66,44]) // 集合将元素中的数组进行重复的剔除
let arr = [...set2] // 使用扩展用算符进行转换为数组
2.es6的map键值类型
map类型是键值对的有序列表,键和值的任意类型 无法被释放
// 声明 map
let map = new Map();
// 进行设置值
map.set("name", '张三') //Map(1) Map(1) {'name' => '张三'}
//循环遍历 key :name val:张三
console.log(map) // Map(0) { size: 0 } 打印的结构
// 获取值
console.log(map.get('name')); // 张三
// 校验值
console.log(map.has('name')) // true
//删除值
console.log(map.delete('name')) // 删除后 打印的结果也是 bool类型
// 清除值
map.clear() //清空值
// 因为这个map结构使数任何类型 key val 可以使任意结构
map.set([11, 2, 3, 44, 5, 6,], 'hello') //{Array(6) => "hello"} 数组: 字符类型
console.log(map);
// 设置多元数组
let m = new Map([["a", 1], ["b", 2]])
console.log(m) // {'a' => 1, 'b' => 2}
10.迭代器
// 迭代器,一种新的遍历机制
const item = ['1',2,55,'asd'] // 设置一个数组类型
let func = item[Symbol.iterator]() // 获取数组走的迭代器
//返回一个函数 ? values() { [native code] }
console.log(func.next()) // {value: '1', done: false}
// 返回的一个对象 value代表时数组中的值 done false 代表是遍历还没有完成 当done为true时,说明便利完成
console.log(func.next())
// {value: undefined, done: true} done为true 说明为遍历完成 value变为 空
/ 迭代器两个核心:
// 1 迭代器是一个接口,能快捷的访问数据 [Symbol.iterator]( 创建迭起,同给迭代器的next的结果
// 2 迭代器遍历数据结构的指针 第一次调用指向了 1 value指向 1 dome为false 以此类推
// 当done 为true时,遍历结束
11.生成器
1.命名生成器
function* func(){
// 这样定义函数就可以使用yield关键字
yield
}
const ite = func() // 这个就是迭代器对象
案例:
创建生成器
function* func(){
let res = yield request('传入的网络地址') // 3.当执行这个迭代第一次时,会执行request函数
//res :res 是谁:恢复执行传入next(实参)
}
const ite = func() //1. 这个就是迭代器对象
ite.next() // 2.恢复yield进行执行 执行这个生成器函数 就会执行 yield中的关键字
function request(url){
$.ajax({
url:url,
method:'get',
success(res){ //执行这个回调函数,在执行yield时会将res传给上一个执行yield 中的变量
ite.next(res) // 4.恢复执行并且 将res传入给 生成器值的变量res
}
})
}
案例二
function* en(){
add() // 执行第一个开始加载提示
yield del() // 卡在加载提示这里,当加载提示执行
func()
}
const ite = en() // 生成器对象
ite.next() // 执行第一次
function add(){
console.log('开始加载... 图片');
}
function func(){
console.log('隐藏加载提示...显示图片')
}
function del(){
// setInterval计时器
setTimeout(() =>{
console.log('加载完成,隐藏加载效果')
// 加载提示执行后执行
// 执行生成器中的下一次next方法
ite.next() // 执行第二次
},5000)
}
12.生成器generator函数
generator 函数 可以通过yield关键字 将函数挂起,为了改变执行流程提供了可读性
为异步编程(解决异步代码)
generator 函数是分段执行,yield语句是暂停执行,next就是恢复执行
//区别
1.function后 函数名前 *
2 只能在函数内部使用yield表达式 让函数挂起
function* func(){
yield 1; // 当使用yield关键字时,就会在这个位置挂起不走,当使用next才会执行
}
// 返回一个遍历器对象, 可以调用next()方法调用
let fn = func() // 返回一个对象给 fn变量 返回遍历器对象
// 使用next()方法 // 可以.value取值 done 获取状态(false还可以next true不能next)
console.log(fn.next().done); //打印的结果就是 {valse:1 ,done:false}
// 当第一次调用next 就会卡在第一个yield
对迭代器传入值:
传入的参数将值给到了执行完毕的 yield中
// 对迭代器的传值
function* add(){
console.log('hehehe');
// x 不是 yield 2 的返回 是当前next 调用 恢复调用yield执行传入的实参
let x = yield "a" // 当使用next时 卡在这个位置
console.log('hahah',x);
let y = yield '123'
console.log('hahahz',y);
return x+y
}
let fn = add()
// 先打印 log 中的数据 在进行打印yield关键字中的内容,函数进行挂起
// 在进行执行next 时就恢复执行
console.log(fn.next(10)); // {value: 'a', done: false}
// 当进行传值时,这个next的值传给乐 let 中的x
// hahah 20
console.log(fn.next(20)); // {value: '123', done: false}
// 当进行传值时 next 中的参数传给y值
// 返回值return x+y找到下一个执行的yield 中的 对value进行赋值,因为最后一次执行done: true
// 所以就赋值到最后一个next 的value中
console.log(fn.next(20)); //{value: 40, done: true}
主要作用就是 不具备 interator 接口的对象提供的遍历操作
// 将不具备 interrator循环的对象 变为可遍历操作
function* func(obj) { // 生成器写法 + yield 挂起
const propkey = Object.keys(obj) // 传入的对象 返回一个迭代器
console.log(propkey);
for (let p of propkey) { // 迭代器就可以进行for of循环
yield [p, obj[p]] // 构造结构 {name:1223} // 使用yield关键字函数挂起
}
}
const obj = {
name: 133,
age: 456
}
console.log(obj); // {name: 133, age: 456} 普通的对象
for (let [key, val] of func(obj)) {
console.log(key, val);
console.log(`${key}:${val}`)
}
13.promise的使用
1.基本知识:
是一种异步的解决方案: 中文名为承诺
promise 相当于一个容器,放置这未来要执行的事件(异步)的一个结果
各种异步操作都可以使用同样的方式进行处理 axios库就是基于promise
特点:
1. 对象的状态不收外接影响 异步处理的状态: peendig(进行中) resolved(成功) rejected(失败了)
这三个状态 保存在peomise
2.一旦改变,就会在变,任何时候都可以 得到结果 进行中- 成功 进行中-失败 都存储在peomise
怎么使用:
1.创建一个promise对象接受回调函数
new Promise(接受一个回调函数)
回调 函数接受两个参数:rejected,resolve 成功和失败(固定写法)
例如:
案例伪造异步操作:
let pro = new Promise(function (rejected, resolved) {
// rejected,resolve 这个参数都是方法
// 执行异步操作
let res = {
code: 200,
data: {
name: '成功了'
},
error: '失败了'
}
// 伪造异步操作
// 使用setTimeout方法定时伪造异步
setTimeout(() => {
if (res.code === 200) { // 如果状态为200
resolved(res.data) // 就将成功的值传给resolved成功状态 可以pro对象中的then() 获取成功的值
} else {
rejected(res.error)
}
}, 1000)
//pro.then() // 成功的结果 执行异步操作的成功的结果 内部接受一个回调函数
val接受的就是成功状态的值
获取存在成功状态下的内容 使用then方法获取成功返回的内的成功信息和错误新
pro.then((val) => { // 接受回调函数
// val 接受成功的数据
console.log(val); //val 接受的是请求成功状态下的data中的错误值和成功值
}, (err) => { // 接受异步请求中请求状态 错误的内容
console.log(err) // 获取请求失败状态下的错误值
})
// 封装异步操作
// ex 接受时间
// 封装了promise 方法,变得更为灵活
function time(ex) {
return new Promise((rejected, resolved) => {
setTimeout(() => {
resolved('成功的信息')
}, ex);
})
}
time(1000).then((val) => {
console.log(val)
})
promise的封装ajax请求
//pormise 封装一个ajax 异步请求
const getJSON = function(url){
//在这个方法中封装一个promise对象
new Promise((reject,resolve)=>{
// 创建一个请求
const xhr = new XMLHttpRequest()
//打开对象
xhr.open('GET',url)
// 设置状态 回调函数
xhr.onreadystatechange = handler
//约定返回数据类型
xhr.responseText = 'json'
//设置请求头
xhr.setRequestHeader('Accept','application/json')
//发送
xhr.send() // get必须写
// 回调函数
function handler(){ // 创建回调函数
// this指向 xhr对象
console.log(this.readyState) // 获取数组的状态
if(this.readyState === 4){
if(this.status === 200){ // 后端请求的状态
resolve(this.response) // 获取的请求体返回
}else{
reject(new Error(this.statusText)) // 讲请求状态的error
}
}
}
})
}
getJSON('url') // 传入地址
.then((val)=>{
console.log(val)
},(error)=>{
console.log(error);
})
//其他pormise中的其他方法
//then() 方法 第一个参数:relove 回掉方法 第二个参数:可选的reject 状态的回调
// then() 返回了什么:返回的时新的pormise实例对象 还可以.then() 可以采用链式写法
// 可以特殊写发 链式写法
getJSON('url').then(val=>{
// 返回正确的操作
}).catch(err=>{
// 返回错误的操作
})
promise的其他
// resolve() reject() all() race() finally() 方法
1.resolve() 方法: 与reject()相同效果
可以其他转换为 promise对象 现有的任何对象转换为
let p = Promise.resolve('foo') //将字符串foo转为promis对象
//等价于
let p = Promise(resolve => {
return resolve('foo')
}) 直接返回foo
console.log(p);
p.then((val) => {
console.log(val); // 结果就是 foo
})
2. all() 并行的执行3个异步
all() 并行的执行这个3个异步 // 一起操作 游戏素材 加载
let p1 =new Promise((resolve,reject)=>{})
let p2 =new Promise((resolve,reject)=>{})
let p3 =new Promise((resolve,reject)=>{})
let lst = [p1,p2,p3]
let p4 = Promise.all(lst) // 传入一个数组
p4.then((val)=>{
// 3个都成功才是成功
}).catch((err)=>{
// 如果一个失败 就全失败
})
3.catch()方法 获取请求失败后的信息
// 请求图片资源
function img(imgs) {
return new Promise((resolve, reject) => {
new imgg = new Image() // Image()函数
img.onload = function () {
resolve(img) // 成功返回img
}
img.src = imgsrc
})
}
// 请求图片时长
function timeout() {
let p = new Promise((resolve, reject) => {
setTimeout(() => {
reject('请求超时')
}, 3000) // 设置时长3秒
})
}
// 参数接受数组 请求成功不会走catch
Promise.rece([img('images/2.peg'), timeout()]).then(res => {
console.log(res); // 如果3秒内请求图片就会执行这里
}).catch(err=>[ ///*****
console.log(err) // 如果3秒后才能请求到就会执行请求超时(打印请求超时提示)
])
// race() finally(()=>{也是一个回调函数}) 不论是promise对象请求数据成功失败 都会执行race() finally()这两个方法
14.async异步
// 使用async 进行异步操作 / 返回一个promise对象 可以统括then 和catch
// async 时gemerator 的一个语法糖
async function f(){
// 这个后台的字符串会被async方法转换为 promis对象
// 字符传会被转换为promis对象
// await命令就是等待
// return await 'await(等待,必须使用async才能使用await命令)等待命令'
//解释版
let s = await '你好 你好 async' //1.s变量执行
let data = await s.split('') // data 等待s变量执行完毕后 在进行执行
return data // 最终返回的时data等待执行后的结果
}
//console.log(f()); // Promise {: undefined} 返回一个promise对象
f().then((val)=>{
console.log(val); //val 就会接受到await 和后面的字符串信息
}).catch((err)=>{
console.log(err);
})
// 假如:async函数中有多个await 那么then函数等待 所有的await指令 运行完毕的结果 才会执行then
解决只有执行await后的才能返回解决
使用try 就算await出现错误,也可以获取正确的结果
//错误的状态下的异步
async function f2(){
// throw 抛出错误对象
// throw new Error('出错误了!!!')
//await '后面必须是一个promise对象,不管是什么类型都会转换为promise对象'
// await 特点就是 如果一个出错执行了错误信息,下面的await不会执行
// await Promise.reject('出错了') // 只会打印出错了,下面的命令就不会执行
// await Promise.resolve('正确的')
// 解决await 出现错误不执行的弊端
try {
await Promise.reject('出错了') // 就算出错
}catch(err){
}
return await Promise.resolve('正确的') // 还是可以出现正确的
}
// catch 接受报错信息
f2().then((val)=>{console.log(val);}).catch((err)=>{console.log(err);})
15.class类的使用
1.类的创建
es5构造类
// 这是一个类
function pe(name,age){
this.name = name
this.age = age
}
// 每个函数都有一个prototype属性,这个属性是指向一个对象的引用,这个对象称为原型对象,
//原型对象包含函数实例共享的方法和属性,
// prototype每个函数都有的一个特点,指向一个应用对象,在对象中有共享的构造方法和属性
pe.prototype.pp = function(){ // 类里面的方法,可以更加创建的对象进行调用
return [this.name,this.age]
}
// 利用pr函数对象内的prototype方法构造一个 pp的公共方法
let p1 = new pe('123','3456') // 创建一个pe类的对象,就可以获取内部的方法
console.log(p1.pp()); // ['123', '3456'] 就可以根据这个对象调用内部的方法
es6构造类
class Person{ // 使用class类
// 创建对象立即被调用
constructor(name,age){ //constructor 这是一个初始化方法,创建类对象时立即被调用相当于python init方法
this.name = name // 赋值属性
this.age = age
}
// 使用new的对象进行调用内部的方法
// 创建方法// 方法名(可以设置参数){进行逻辑判断}
sayname(){
return this.name
}
sayage(){
return this.age
}
}
let p1 = new Person('aa',123)
console.log(p1); // Person {name: 'aa', age: 123}
// 使用创建的对象// 调用对象需要加()进行执行,和python中的class类中的方一致
console.log(p1.sayage()); //123
console.log(p1.sayname()); //aa
从外部进行创建类
// 通过外部进行对类中设置方法 Object.assign
// 传入两个参数1 当前的类名.prototype方法 2传入一个对象,对象中函数名(){}
Object.assign(Person.prototype,{
sayxx(){
return xx
},
sayzz(){
return yy
}
})
如何继承类
// 类的继承 使用关键字extends
// 创建类不用加上()
class animal {
// es6 中的初始化方法 // 没有类对象
constructor(name, age) {
this.name = name //事例对象
this.age = age // 事例对象
}
//创建两个对象
show() {
return this.name
}
func() {
return this.age
}
}
//继承这个animal类
// 使用extends 继承animal 父类
//dog 类继承animal类
// class 关键字 子类名 extends方法 父类名
// class dog extends animal{
// }
class dog extends animal{
// 子类的初始化方法,因为继承了父类的变量
constructor(name,age,color){
super(name,age) // 直接使用super去找父类的变量就可以
this.color = color
}
// 子类的自己的方法
saycole(){
return `${this.name}${this.age}`
}
//重写父类的方法
func() {
return `${this.name}${this.age}`
}
}
// 创建子类的对象
let p1 = new dog('aa',18,'red') // p1是事例话dog 的对象
console.log(p1); // 返回了dog的对象,内部有父类的方法和父类的事例变量
//执行父类中的方法
console.log(p1.show());
//执行子类的方法
console.log(p1.color());
16.模块化语法
html 接受