ES6的新特性之迭代器与循环

我们知道遍历数组的方式之一就是 使用for循环、while循环或do…while循环来遍历,如:


var arr = [1, 2, 3, 4, 5];
for (var i = 0; i < arr.length; i++) {
    console.log(arr[i]);    //1,2,3,4,5
}

ES5发布之后,可以使用 数组的forEach() 迭代方法来遍历数组:


var arr = [1, 2, 3, 4, 5];
 
arr.forEach(function (value) {
    console.log(value);   //1,2,3,4,5
});

但有一个小小的缺陷:就是不能使用break、continue语句等来中断函数,也不能使用return语句返回到外层函数。

还可以使用 for-in枚举方法 来遍历数组


var arr = [1, 2, 3, 4, 5];
 
for (var i in arr) {
    console.log(i); //返回的是索引 0,1,2,3,4 
    console.log(arr[i]); //返回的是数组项的值 1,2,3,4,5 
    console.log(typeof(i));  //返回的是 string,string,string,string,string,string 字符串

  • for-in除了可以遍历数组外,还可以遍历自定义属性,也就是可以枚举可枚举属性。可是在遍历数组时,它还额外执行一次,用于遍历可枚举属性,但是这是我们不需要的操作。甚至还会遍历到数组原型链上的属性,这更是一个大麻烦。
  • for-in循环还有一个更大的缺点:那就是它会以随机次序遍历数组元素,这更是我们不想要的。也就是说它遍历出的元素的顺序不是数组中真正的顺序。

for-in 用于遍历字符串类型的键在这里插入图片描述
for-of 用于遍历字符串类型的值
在这里插入图片描述

for-of循环
在ES6中,有一个新的特性for-of循环可以用来遍历数组:


var arr = [1, 2, 3, 4, 5];
 
for (var i of arr) {
    console.log(i);   //1,2,3,4,5

for-of循环的优点:

  1. 更为简单更为直接的能遍历数组
  2. 避开了for-in循环的所有缺点
  3. 与forEach()不同的是,for-of循环可以使用break、continue、return等语句来中断函数的运行。
  4. for-in循环主要用于对象属性的遍历。
  5. for-of循环用于遍历数据–如对数组元素的遍历

for -of对其它集合的遍历

for-of循环不仅用于数组,还可以用于数组对象等,如DOM中的nodeList等,可以用来遍历DOM中的子节点、根据给定条件返回的元素节点的集合等。

for-of循环还可以用于遍历字符串

var str = "hello ES6";
 
for (var i of str) {
    console.log(i); //h e l l o  E S 6
}

for-of循环还支持对MapSet对象的遍历

Array

定义: 有序并且可以重复的集合

Array.xxx:

  1. Array.isArray() 判断某一个变量是否为一个数组 【es5】
  2. Array.from() 【es6】
  3. Array.of() 【es6】

Array.prototype.xxx

  1. find()
  2. findIndex() 返回值的是匹配元素的索引
  3. includes()
  4. keys() 返回值是遍历数组索引的迭代器
  5. values() 返回数组元素的迭代器
  6. entries() 返回遍历数组中key-val的entry的迭代器

Set
定义: 无序不可以重复的集合
实例化

  1. new Set()
  2. new Set(可迭代的对象)

//会遍历并且自动去重

  1. Array.from(new Set(“hello”))
  2. Array.from(new Set(“hello”)).join()
  3. Array.from(new Set(“hello”)).join("")
  4. […new Set(“hello”)]

迭代器Iterator

Iterator 是 ES6 引入的一种新的遍历机制,迭代器有两个核心概念

  • 迭代器是一个统一的接口,它的作用是使各种数据结构可被便捷的访问,它是通过一个键为Symbol.iterator 的方法来实现。
  • 迭代器是用于遍历数据结构元素的指针(如数据库中的游标)。

迭代过程

迭代的过程如下:

  • 通过 Symbol.iterator 创建一个迭代器,指向当前数据结构的起始位置
  • 随后通过 next 方法进行向下迭代指向下一个位置, next 方法会返回当前位置的对象,对象包含了 value 和 done 两个属性, value 是当前属性的值, done 用于判断是否遍历结束
  • 当 done 为 true 时则遍历结束
    在这里插入图片描述
    在这里插入图片描述

上面的例子,首先创建一个数组arr,然后通过 Array.iterator 方法创建一个迭代器,之后不断的调用 next 方法对数组内部项进行访问,当属性 done 为 true 时访问结束。

迭代器是协议(使用它们的规则)的一部分,用于迭代。该协议的一个关键特性就是它是顺序的:迭代器一次返回一个值。这意味着如果可迭代数据结构是非线性的(例如树),迭代将会使其线性化。

可迭代的数据结构

以下是可迭代的值:

  1. Array
  2. String
  3. Map
  4. Set
  5. Dom元素(正在进行中)

Array

引: 数组的创建方式
new Array(3,2)
[…string]

  1. Array.from(v)

注意: v为类数组对象或者可遍历的对象

let array_like = {"0":"terry","1":"larry",length:2}
console.log(array_like);

// 从数组对象中解构出来slice方法 let {slice} = [];
//1. 使用原始的Array.prototype.slice转换

console.log(slice.call(array_like,0));

//2. 使用Array.from转换

console.log(array_like);
console.log(Array.from(array_like));

//3. 使用Array.from转换可以遍历的对象

let set = new Set([1,2,3,1,2,4,5,6]);
console.log(set);
console.log(Array.from(set));

  1. Array.of(p1,p2,…)
  2. Array.prototype.includes
  3. Array.prototype.find
  4. Array.prototype.findIndex

let arr = [
	{name:"terry",age:12},
	{name:"tom",age:14},
	{name:"larry",age:13},
	{name:"jacky",age:18},
	{name:"vicky",age:11}
]
//let result = arr.find(item=>item.age === 13)
let result = arr.find(function(item){
	return item.age === 13
})
console.log(result);
  1. Array.prototype.fill

new Array(3).fill(9)

  1. Array.prototype.keys 对键的遍历
  2. Array.prototype.values 对值的遍历
  3. Array.prototype.entries 对键值对的遍历

数组的迭代


let arr = ["terry","larry","tom","jacky"];
//1. 获取迭代器
let values_iterator = arr.values();
//2. 通过迭代器获取数组中的元素
let item ;
while(!(item = values_iterator.next()).done){
	console.log(item.value);
}
//3. 使用for-of遍历迭代器let entry_iterator = arr.entries();
for(let entry of entry_iterator){
	console.log(entry);
}
//4. 使用for-of遍历数组
for(let item of arr){
	console.log(item);
}

string

字符串是可迭代的,单他们遍历的是 Unicode 码,每个码可能包含一个到两个的 Javascript 字符。

for (const c of 'z\uD83D\uDC0A') {
    console.log(c);
}
// output:
// z
// \uD83D\uDC0A

Set

定义: 无序不可以重复的集合(数组中的元素可以重复),Set 本身是一个构造函数,用来生成 Set 数据结构。

特点: Set 函数可以接受一个数组(或者具有 iterable 接口的其他数据结构)作为参数,用来初始化。

[…new Set(array)] // 去除数组的重复成员

  1. 实例化Set对象

let set = new Set();
let set = new Set([1,2,3,1,2])

  1. Set.prototype.xxx
    size 返回Set实例的成员总数
    add(val) 添加某个值,返回Set结构本身
    delete(val) 删除某个值,返回一个布尔值,表示删除是否成功
    has(val) 返回一个布尔值,表示该值是否为Set的成员
    clear() 清除所有成员,没有返回值
    forEach() 使用回调函数遍历每个成员
    keys() 返回键名的遍历器
    values() 返回键值的遍历器
    entries() 返回键值对的遍历器
const set = new Set();
set.add("zero");
set.add("one");
 
for (let item of set) {
  console.log(item);
}
// output:
// zero
// one

Map

key可以为任意数据对象(对象的key只能为字符串)

  1. 实例化map对象

let map = new Map();
let map = new Map(entry);

  1. Map.prototype.xxx
    size
    set(key,val) 向map中添加键值对,key不可以重复,如果重复,value更新
    get(key) 通过key获取value
    has(key) 判断map集合中是否存在指定的key
    delete(key) 通过key从map集合中删除
    clear() 清空map集合
    keys() 迭代器对象
    values() 迭代器对象
    entries() 迭代器对象
const map = new Map();
map.set(0, "zero");
map.set(1, "one");
 
for (let item of map) {
  console.log(item);
}
// output:
// [0, "zero"]
// [1, "one"]

类数组对象到数组的转换

Array.prototype.slice.call(arrayLike,0)

arguments

arguments 目前在 ES6 中使用越来越少,但也是可遍历的

function args() {
  for (let item of arguments) {
    console.log(item);
  }
}
args("zero", "one");
// output:
// zero
// one

普通对象不可迭代

原因: 普通对象是由 object 创建的,不可迭代

// TypeError
for (let item of {}) { 
  console.log(item);
}

总结:

  1. 未来JavaScript还有许多的新的集合类型出现,那么for-of循环就是用来遍历这些新的集合类型的。
  2. for-of循环不支持对普通对象的遍历,for-of循环语句通过方法调用来遍历各种集合。
  3. 如果想遍历普通对象,可以使用for-in循环,for-in循环主要是遍历对象的属性的(键/值)。
  4. 数组、Map、Set对象以及其它对象有一个共同点:它们都有一个迭代器方法。
  5. 可以为任何类型的对象添加迭代器方法。
    当我们向任意对象添加 Symbol.iterator 方法后,就可以遍历这个对象了。
  6. Symbol是ES6中的一个新特性,所有拥有Symbol.iterator方法的对象被称为可迭代的
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值