寒假学习——ES6(3)
迭代器(iterator)
任何数据结构只要部署iterator接口,就可以完成遍历操作
for of
循环- 原生具备该接口的数据(可用for of 遍历)
- Array
- Arguments
- Set
- Map
- String
- TypedArray
- NodeList
for in保存的是键名,for of保存的是键值
- 原理:创建一个指针对象指向数组起始位置,第一次调用next方法指针指向第一个成员,之后一个个移动去遍历,直到最后一个成员
每次调用next方法的时候会返回一个包含value和done两个属性的对象
<script>
const fruit=['猕猴桃','菠萝蜜','香蕉'];
let iterator=fruit[Symbol.iterator]();
console.log(iterator.next());
</script>
迭代器例子(自定义数据遍历)
<script>
const studio = {
name: 'homyit',
member: ['3qq', 'hh', 'll', 'tt', 'db', 'xx', ],
[Symbol.iterator]() {
let index = 0;
let _this = this; //因为如果直接用this的话它的作用域是return那个大括号而不是整个这个对象,所以要用一个临时变量保存一下或者用箭头函数也行
return {
//要返回一个next方法一个value属性,一个done属性
next: function () {
if (index < _this.member.length) {
const result = {
value: _this.member[index],
done: false
}
index++;
return result;
} else {
return {
value: undefined,
done: true
};
}
}
}
}
}
//对对象的那个成员属性进行遍历
for(let i of studio){
console.log(i);
}
</script>
生成器
- 本质:就是一个特殊的函数
- 作用:异步编程
- 声明形式:
function * 函数名(参数){函数体}
- 执行语句直接调用不会执行要通过next方法
- 函数代码分隔符:yeild语句,后面+表达式或者自变量,将函数分成几段,分别用几次next来执行
<script>
function * gen(){
console.log("第一个代码段");
yield '1';
console.log("第二个代码段");
yield '2';
console.log("第三个代码段");
yield '3';
console.log("第四个代码段");
}
let iterator=gen();
//console.log(iterator);//返回一个迭代器对象
iterator.next();//四次调用next分别输出四个代码段的输出语句内容
iterator.next();
iterator.next();
iterator.next();
</script>
如果单独调用next则输出分隔代码段的内容,如果打印这个next方法会发现next方法的value值就是yeild语句的内容
- 生成器传参:
- next的参数作为前一个yeild语句的返回值
<script>
function * gen(args){
console.log(args);
let one=yield '第一个';
console.log(one);
let two=yield '第二个';
console.log(two);
}
let ite=gen('aaa');//可以打印出实参
ite.next();
ite.next("第一个yeild语句的返回值");
ite.next("第二个yeild语句的返回值");
</script>
- 生成器实例
<script>
//异步编程 文件操作 网络操作(ajax request) 数据库操作
//实现1s后控制台输出111,2s后控制台输出222,3s后控制台输出333
//本来是三层回调现在可以借助内嵌next方法实现
function one(){
setTimeout(()=>{
console.log(111);
ite.next();
},1000)
}
function two(){
setTimeout(()=>{
console.log(222);
ite.next();
},2000)
}
function three(){
setTimeout(()=>{
console.log(333);
ite.next();
},3000)
}
function *gen(){
yield one();
yield two();
yield three();
}
let ite=gen();
ite.next();
</script>
Promise
- 实质:是一个构造函数可以实例化对象
- 作用:用来封装异步操作并可以获取其成功或失败的结果
- then方法:如果状态是成功调用参数的第一个回调函数,如果是失败调用第二个
<script>
const p = new Promise(function (resole, reject) {
setTimeout(function () {
// let data = '用户数据';
// resolve (data);//让promise状态变成成功,通过then的第一个方法提取数据
let err='数据读取失败';
reject(err);//调用第二个函数参数
}, 1000);
}); //传入一个函数作为参数
//调用promise对象的then方法,两个函数参数,如果上面调用了resolve这里就会执行then的第一个函数参数
p.then(function (value) {
console.log(value);
}, function (reason) {
console.log(reason);
})
</script>
- Proomise封装读取文件
const fs=require('fs');
//两个参数一个路径一个函数
fs.readFile('./好好学习.md',(err,data)=>{
if(err) throw err;
console.log(data.toString());
});
//用Promise封装
const p=new Promise(function(resolve,reject){
fs.readFile("./好好学习.md",(err,data)=>
{
//如果失败
if(err) reject(err);
//如果成功
resolve(data);
});
});
//通过then方法来指定回调
p.then(function(value){
console.log(value.toString());
},function(reason){
console.log("读取文件失败");
});
- Promise封装AJAX
<script>
const p = new Promise((resolve, reject) => {
//1.创建对象
const xhr = new XMLHttpRequest();
//2.初始化
xhr.open("GET","https://api.apiopen.top/getJoke");
//3.发送
xhr.send();
//4.绑定事件,处理响应结果
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.error(reason);
})
</script>
- Promise的then方法解析
- 1.如果回调函数中返回的结果是非promise对象(包括没有返回值的情况此时为undefined),状态就是成功,返回值就是那个非promise对象
- 2.是一个Promise对象返回该对象的内容
- 3.抛出错误:
<script>
const p=new Promise((resolve,reject)=>{
setTimeout(() => {
// resolve("用户数据");
reject('出错啦');
}, 1000);
});
//调用then方法,该方法返回的值是Promise对象,对象状态由回调函数的执行结果决定
const result=p.then(value=>{
console.log(value);
//return 'honghong'
return new Promise((resolve,reject)=>{
reject('error');
})//如果then方法中的参数函数返回的是promise对象
// throw new Error('出错了哦');
},reason=>{
console.warn(reason);
})
console.log(result);
</script>
- 因为then方法返回结果是Promise所以可以链式调用
p.then(value=>{},reason=>{}).thenthen(value=>{},reason=>{})
集合与API
- Set集合
- 实质:是一种新的数据结构类似于数组
- 实现了iterator接口可以用扩展运算符和for of进行遍历
- 属性与方法:
- size:返回元素个数,相当于数组的length
- add:增加一个新元素返回当前集合
- delete:删除元素,返回boolean值
- has:检测是否包含某个元素,返回布尔值
<script>
let s = new Set(); //可传参或者不传参
let s2 = new Set(['apple', 'banana', 'apple']);
console.log(s2);//会进行去重与数学中集合概念很像
s2.add('orange');//同理可以对其他几个属性进行测试
</script>
- 例子
<script>
//数组去重
let arr1=['红红','橙橙','黄黄','绿绿','红红'];
let result=[...new Set(arr1)];//数组
console.log(result);
//找交集
let arr2=['橙橙','黄黄','绿绿','蓝蓝'];
let result2=[...new Set(arr1)].filter(item=>{
let s2=new Set(arr2);
if(s2.has(item)){
return true;
}else{
return false;
}
});
console.log(result2);
</script>
Map
- 实质:一个新的数据结构,是键值对的集合,键可以是各种类型的值,对象也可以
- 实现了iterator接口所以也可用扩展运算符和for of进行遍历
- 相关属性和方法: