1.迭代器
迭代器(Iterator)就是这样一种机制。它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署Iterator接口,就可以完成遍历操作(即依次处理该数据结构的所有成员)
Iterator 的作用有三个:一是为各种数据结构,提供一个统一的、简便的访问接口;二是使得数据结构的成员能够按某种次序排列;三是ES6创造了一种新的遍历命令for...of循环,Iterator接口主要供for...of消费。
Iterator 的遍历过程是这样的。
创建一个指针对象,指向当前数据结构的起始位置。也就是说,遍历器对象本质上,就是一个指针对象。
第一次调用指针对象的next方法,可以将指针指向数据结构的第一个成员。
第二次调用指针对象的next方法,指针就指向数据结构的第二个成员。
不断调用指针对象的next方法,直到它指向数据结构的结束位置。
1.迭代器实现了Iterator接口,只要有实现了Iterator就可以使用for-of遍历 let arr=[1,2,3,4,5]; console.log(arr.keys()); console.log(arr.values()); console.log(arr.entries()); // keys values entries 当前变量是迭代器对象 // 迭代器对象实现了Iterator接口,只要实现了迭代接口就可以使用for-of 遍历 // let [a,b]=10; 报错10 is not iterable let str='hello'; //实现了迭代器接口,可以遍历 // console.log(a,b); for(let key of str){ console.log(key) } // 以前遍历字符串 let [...a]=str; console.log(a) let result=str.split("") console.log(result); for(i=0;i<str.length;i++){ console.log(str.charAt(i)) } 遍历迭代器对象 let keys=arr.keys() for(let key of keys){ console.log(key) } let values=arr.values(); for(let value of values){ console.log(value,'--------') } let entries=arr.entries(); for(let entry of entries){ console.log(entry) } while(!(result=keys.next()).done){ console.log(result) } for-of实现原理就是调用迭代器的next()方法,第一次调用将指针指向数据结构的第一个成员,依次调用依次指向,直到没有成员可以指向,done为true 迭代过程:创建一个指针对象,指向当前的数据结构起始位置; 第一次调用指针对象的next方法,指向数据结构的第一个成员; 第二次调用指针对象的next方法,指向数据结构的第二个成员; 直到done为true,指向数据结构的结束位置; let keys=arr.keys(); let values=arr.values(); let entries=arr.entries() console.log(keys.next()) console.log(keys.next()) console.log(keys.next()) console.log(keys.next()) console.log(keys.next()) console.log(keys.next()) console.log(entries.next())
原生具备 Iterator 接口的数据结构如下 Array、Map、Set、String、TypedArray、arguments、NodeList
2.Set
Set类似于数组,但是成员的值都是唯一的,没有重复的值。Set 本身是一个构造函数,用来生成 Set 数据结构。Set 构造函数可以接受一个数组(或者具有 iterable 接口的其他数据结构)作为参数,用来初始化。
Set API var set=new Set() //创建Set集合 成员是唯一的,key-value是一样的 //添加元素 set.add('hello'); set.add('world'); set.add('world'); console.log(set); // 删除元素 set.delete('hello'); console.log(set); // 遍历 let keys=set.keys() let values=set.values() let entries=set.entries(); console.log(keys,values,entries); set.forEach((value)=>{ console.log(value) }) //判断有没有某个成员 set.has('hello');返回布尔值true或者false //清空set set.clear(); //返回set成员个数 set.size ------------------------------------------------ set应用 set构造函数可以接受数组或者其他可遍历的数据结构 let set=new Set([1,2,3,4,1,2,3,4]); console.log(set); //数组去重 let arr=[1,2,3,5,3,2]; let result=new Set(arr); console.log(result); //将字符串转换为数组 let [...arr1]='hello'; //将set集合转换为数组 let [...arr2]=result; console.log(arr2); console.log([...new Set(arr)]) let s = new Set(); s.add([1]); s.add([1]); console.log(s); console.log(s.size);
3.Map集合
Map类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。也就是说,Object 结构提供了“字符串—值”的对应,Map结构提供了“值—值”的对应,是一种更完善的 Hash 结构实现。如果你需要“键值对”的数据结构,Map 比 Object 更合适。Map 可以接受一个数组作为参数。该数组的成员是一个个表示键值对的数组。
let obj={ name:"zhangsan", age:12 } //遍历键值对组成的数组 let arr=Object.entries(obj); console.log(arr); //将数组作为参数放到Map中 let map=new Map(arr) console.log(map); // 添加元素 map.set('1','1'); console.log(map); // 删除元素 map.delete('name'); console.log(map); // 获取元素 console.log(map.get('age')); // 遍历 let keys=map.keys() let values=map.values() let entries=map.entries(); console.log(keys,values,entries); map.forEach((value,key)=>{ console.log(value,key) })
Map Object 意外的键 Map 默认情况不包含任何键。只包含显式插入的键。 一个 Object 有一个原型, 原型链上的键名有可能和你自己在对象上的设置的键名产生冲突。 键的类型 一个 Map的键可以是任意值,包括函数、对象或任意基本类型。 一个Object 的键必须是一个 String 或是Symbol。 键的顺序 Map 中的 key 是有序的。因此,当迭代的时候,一个 Map 对象以插入的顺序返回键值。 一个 Object 的键是无序的。注意:自ECMAScript 2015规范以来,对象确实保留了字符串和Symbol键的创建顺序; 因此,在只有字符串键的对象上进行迭代将按插入顺序产生键。 Size Map 的键值对个数可以轻易地通过size 属性获取 Object 的键值对个数只能手动计算 迭代 Map 是 iterable 的,所以可以直接被迭代。 迭代一个Object需要以某种方式获取它的键然后才能迭代。 性能 在频繁增删键值对的场景下表现更好。 在频繁添加和删除键值对的场景下未作出优化。
4.数值扩展
Number.isFinite(), Number.isNaN()
与isFinite、isNaN不同,这两个新方法只对数值有效,
Number.isFinite()
对于非数值一律返回false
,Number.isNaN()
只有对于NaN
才返回true
,非NaN
一律返回false
。
Number.isFinite(0.8); // true Number.isFinite(NaN); // false Number.isFinite(Infinity); // false Number.isNaN(NaN) // true Number.isNaN(15) // false
Number.parseInt(), Number.parseFloat()
ES6 将全局方法
parseInt()
和parseFloat()
,移植到Number
对象上面,行为完全保持不变。
Number.parseInt('12.34') // 12 Number.parseFloat('123.45#') // 123.45
Number.isInteger()
Number.isInteger()
用来判断一个数值是否为整数。
Number.isInteger(25) // true Number.isInteger(25.1) // false
async异步函数
async函数是使用async关键字声明的函数。 async函数是AsyncFunction构造函数的实例, 并且其中允许使用await关键字。async和await关键字让我们可以用一种更简洁的方式写出基于Promise的异步行为,而无需刻意地链式调用promise。
await关键字只在async函数内有效。如果你在async函数体之外使用它,就会抛出语法错误 SyntaxError 。async/await的目的为了简化使用基于promise的API时所需的语法。async/await的行为就好像搭配使用了生成器和promise。async函数一定会返回一个promise对象。如果一个async函数的返回值看起来不是promise,那么它将会被隐式地包装在一个promise中。
简单来说 是一个函数,是一个异步编程解决方案,内部封装了generator函数,是一个语法糖,内部自带执行器,与await配合使用;异步编程,同步处理;
async function loadArticle() { try { let res = await axios.get('http://122.199.0.35:8888/index/category/findAll') console.log(res.data.data); } catch(error) { throw new Error('请求失败'); } finally { console.log('最终执行'); } } loadArticle()
forEach、for in、for of三者区别 forEach更多的用来遍历数组 for in 一般常用来遍历对象或json for of数组对象都可以遍历,遍历对象需要通过和Object.keys()