目录
rest参数
arguments生成的是对象,rest参数生成数组
形式为:...变量名
它可以把一个分离的参数序列整合成一个数组,常用于获取函数的多余参数,或者处理函数参数个数不确定的情况
迭代器 Iterator
是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署Iterator接口,就可以完成遍历操作。这里指的Iterator一个接口就是对象里的一个属性。
ES6新增for...of循环,Iterator接口主要供for...of消费
原生具备Iterator接口可用的数据有:Array、Arguments、Set、Map、String、TypedArray、NodeList
工作原理
1.创建一个指针对象,指向当前数据结构的起始位置
2.第一次调用对象的next方法,指针自动指向数据结构的第一个成员
3.接下来不断调用next方法,指针一直往后移动,直到指向最后一个成员
4.每调用next方法返回一个包含value和done属性的对象
注:需要自定义遍历数组的时候要想到迭代器
实现自定义遍历数据
const className = {
name:'3.2',
stus:[
'123',
'456',
'789',
'101'
],
[Symbol.iterator]() {
let index = 0
return {
next: () => {
if(index < this.stus.length) {
const result = {value:this.stus[index],done:false}
index++
return result
} else {
const result = {value:undefined,done:true}
return result
}
}
}
},
}
for(let x of className) {
console.log(x);
}
生成器
生成器就是一个特殊的函数,异步编程新的解决方案
yield 可以理解为函数代码的分隔符
生成器函数的参数
第二次调用next方法,传入实参,将作为第一个yield(one)的整体返回结果
生成器函数实例
实现1s后输出111,2s后输出222,3s后输出333
//回调地狱
setTimeout(() => {
console.log(111);
setTimeout(() => {
console.log(222);
setTimeout(() => {
console.log(333);
},3000)
},2000)
},1000)
//生成器函数
function one() {
setTimeout(() => {
console.log(111);
iterator.next()
},1000)
}
function two() {
setTimeout(() => {
console.log(222);
iterator.next()
},2000)
}
function three() {
setTimeout(() => {
console.log(333);
iterator.next()
},3000)
}
function * gen() {
yield one();
yield two();
yield three();
}
let iterator = gen()
iterator.next()
模拟获取用户数据,订单数据,商品数据
实现一秒输出用户数据,再一秒输出订单数据,再商品数据
function getUsers() {
setTimeout(() => {
let data = '用户数据'
iterator.next(data)
},1000)
}
function getOrders() {
setTimeout(() => {
let data = '订单数据'
iterator.next(data)
},1000)
}
function getGoods() {
setTimeout(() => {
let data = '商品数据'
iterator.next(data)
},1000)
}
function * gen() {
let users = yield getUsers();
console.log(users);
let orders = yield getOrders();
console.log(orders);
let goods = yield getGoods();
console.log(goods);
}
let iterator = gen()
iterator.next()
含参数的iterator.next(data),会作为上一个yield的返回结果
Promise
Promise是ES6引入的异步编程的新解决方案,Promise是一个构造函数
用来封装异步操作并可以获取其成功或失败的结果
const p = new Promise(function(resolve,reject) {
setTimeout(function(){
let data = '用户中的数据库'
//resolve
resolve(data)
},1000 )
});
p.then(function(value) {
//成功之后的操作
}, function(reason) {
//失败之后的操作
})
Promise封装读取文件
.js
//1.进入fs模块
const fs = require('fs');
//2.引用方法读取文件
// fs.readFile('../resource/数据.md',(err,data) => {
// if(err) throw err;
// console.log(data.toString());
// })
//3.使用promise封装
const p = new Promise(function(resolve,reject) {
fs.readFile('../resource/数据.md',(err,data) => {
if(err) reject(err)
resolve(data)
});
});
p.then(function(value) {
console.log(value.toString());
}, function(reason) {
console.log('error');
})
Promise封装AJAX
const p = new Promise((resolve,reject) => {
const xhr = new XMLHttpRequest();
xhr.open('GET','https://api.apiopen.top/getJoke');
xhr.send();
xhr.onreadystatechange = function() {
if(xhr.readyState === 4) {
if(xhr.status >= 200 && xhr.status < 300) {
resolve(xhr.response);
} else {
reject(xhr.status)
}
}
}
})
p.then(function(value) {
console.log(value);
},function(reason) {
console.log(reason);
})
Promise.then
调用then方法的返回结果是Promise对象
对象状态由回调函数的执行结果而定
1.如果回调函数中返回的结果是非Promise类型的属性,状态为成功,返回值为对象的成功的值
2.如果回调函数中返回的结果是promise对象,状态为内层promise的状态
3.如果回调函数中返回的结果位抛出错误,则状态为失败
then方法可以链式调用
Promise读取多个文件
//引入fs模块
const fs = require('fs');
// fs.readFile('../resource/stay.md',(err,data1) => {
// fs.readFile('../resource/to die for.md',(err,data2) => {
// fs.readFile('../resource/数据.md',(err,data3) => {
// let result = data1 + '\r\n' + data2 + '\r\n' + data3
// console.log(result);
// })
// })
// })
//使用promise实现
const p = new Promise((resolve,reject) => {
fs.readFile('../resource/stay.md',(err,data) => {
resolve(data)
})
})
p.then(value => {
return new Promise((resolve,reject) => {
fs.readFile('../resource/to die for.md',(err,data) => {
resolve([value,data])
})
})
}).then(value => {
return new Promise((resolve,reject) => {
fs.readFile('../resource/数据.md',(err,data) => {
value.push(data)
resolve(value)
})
})
}).then(value => {
console.log(value.join('\r\n'));
})
catch方法
const p = new Promise((resolve,reject) => {
setTimeout(() => {
reject('error')
},1000)
})
// p.then((value) => {},reason => {
// console.warn(reason);
// })
p.catch(reason => {
console.warn(reason);
})
class
ES6提供了更接近传统语言的写法,引入了Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。基本上,ES6的class可以看作只是一个语法糖,它的绝大部分功能,ES5都可以做到,新的 class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而己。
ES5通过构造函数实例化方法
class静态成员
实例对象上是没有构造函数上的方法和属性的
实例对象的属性和构造函数原型对象上的方法和属性是相通的
静态成员
static标注的属性和方法属于类而不属于实例对象
继承
es5使用构造函数实现继承
function Phone(brand,price) {
this.brand = brand;
this.price = price
}
function smartPhone(brand,price,color,size) {
Phone.call(this,brand,price)
this.color = color
this.size = size
}
smartPhone.prototype = new Phone
smartPhone.prototype.constructor = smartPhone
smartPhone.prototype.photo = function() {
console.log('我可以拍照');
}
const chuizi = new smartPhone('锤子',999,'black','5.5')
console.log(chuizi);
es6类继承
class Phone {
//构造方法
constructor(brand,price) {
this.brand = brand;
this.price = price
}
//父类成员属性
call() {
console.log('我可以打电话');
}
}
class SmartPhone extends Phone {
//构造方法
constructor(brand,price,color,size) {
//子类调用父类的构造方法作为初始化
super(brand,price); //Phone.call(this,brand,price)
this.color = color
this.size = size
}
photo() {
console.log('take photo');
}
}
const xiaomi = new SmartPhone()
console.log(xiaomi);
子类对父类方法的重写
在JS class语法里,子类不能直接调用父类的同名方法,
class中的getter和setter
get属性的返回值就是属性的值
set必须有参数
get可用于动态属性
set可用于判断
ES6模块化
模块化语法主要由两个命令组成:export和import
export命令用于规定模块的对外接口
import命令用于输入其他模块提供的功能
暴露export
分别暴露
统一暴露
默认暴露
引入import
html中的script标签要设置src="module"
通用导入方式
import * as xxx from './xxx.js'
解构赋值形式
import {xxx} from './xxx.js'
//如果名字重复可以使用as起别名
import {xxx as yy} from './yy.js'
//默认暴露时
import {default as m2} from './m2.js'
3.简便形式
只针对默认暴露
import m2 from './m2.js'
浏览器使用ES6模块化方式
app.js
import * as m1 from './m1.js'
index.html
<script scr='./app.js' type='module'></script>
项目中使用ES6模块化方式
babel:下一代JS语法编译器,能将es比较新的特性语法转化为浏览器能识别的语法
1.安装工具 babel-cli babel-preset-env browserify(webpack)
2. npx babel src/js -d dist/js
3.打包 npx browserify dist/js/app.js -o dist/ bundle.js
async和await
async和await两种语法结合可以让异步代码像同步代码一样
async函数
函数的返回结果是promise对象
promise对象的结果由async函数执行的返回值决定
async function fn() {
//返回一个字符串
//只要返回的结果不是promise类型的对象,则这个函数的返回结果就是成功的promise
//return '123'
//抛出错误,返回的结果是一个失败的promise
throw new Error('error')
}
const result = fn()
console.log(result);
如果返回的结果是一个promise,函数的结果由promise状态决定
await表达式
await必须写在async函数中(单向依赖)
await右侧的表达式一般为promise对象
await返回的是promise成功的值
await的promise失败了就会抛出异常,需要通过try...cathc捕获处理
async和await结合读取文件内容
const fs = require('fs')
function readData() {
return new Promise((resolve,reject) => {
fs.readFile('../resource/数据.md',(err,data) => {
//如果失败
if(err) {
reject(err)
}
//如果成功
resolve(data)
})
})
}
function readStay() {
return new Promise((resolve,reject) => {
fs.readFile('../resource/stay.md',(err,data) => {
//如果失败
if(err) {
reject(err)
}
//如果成功
resolve(data)
})
})
}
function readDTo() {
return new Promise((resolve,reject) => {
fs.readFile('../resource/to die for.md',(err,data) => {
//如果失败
if(err) {
reject(err)
}
//如果成功
resolve(data)
})
})
}
//声明async函数
async function main() {
//await返回结果是函数成功的值
let data = await readData();
let stay = await readStay();
let toDie = await readDTo();
console.log(data.toString());
}
main()
async和await发送AJAX请求
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>发送AJAX请求</title>
</head>
<body>
</body>
<script>
function sendAJAX(url) {
return new Promise((resolve,reject) => {
const xhr = new XMLHttpRequest()
xhr.open('GET',url)
xhr.send()
xhr.onreadystatechange = function() {
if(xhr.readyState === 4) {
if(xhr.status >= 200 && xhr.status < 300) {
//成功了
resolve(xhr.response);
} else {
reject(xhr.status);
}
}
}
})
}
//promise then方法测试
sendAJAX('https://api.apiopen.top/getJoke').then(value => {
console.log(value);
return sendAJAX('https://api.apiopen.top/getJoke')
}).then(value => {
console.log(value);
})
//async和await测试
// async function main() {
// let result = await sendAJAX('https://api.apiopen.top/getJoke')
// console.log('1' + result);
// let result2 = await sendAJAX('https://api.apiopen.top/getJoke')
// console.log('2' +result2);
// }
// main()
</script>
</html>