}
技巧1: 添加以下代码, 使 for…of 可以遍历 jquery 对象:
$.fn[Symbol.iterator] = [][Symbol.iterator];
技巧2: 利用 Generator 重新包装对象:
function* entries(obj){
for(let key of Object.keys(obj)){
yield [key, obj[key]];
}
}
var obj = {
red: “#ff0000”,
green: “#00ff00”,
blue: “#0000ff”
};
for(let [key, value] of entries(obj)){
console.log(${key}: ${value}
); //依次输出 “red: #ff0000”, “green: #00ff00”, “blue: #0000ff”
}
几种遍历方法的比较
-
for 循环: 书写比较麻烦
-
forEach方法: 无法终止遍历
-
for…in: 仅遍历索引, 使用不便捷; 会遍历原型链上的属性, 不安全; 会遍历非数字索引的数组属性;
-
for…of:
iterator 与 [Symbol.iterator]
iterator 遍历过程是这样的:
1. 创建一个指针对象, 指向当前数据结构的起始位置。即遍历器的本质就是一个指针。
2. 调用一次指针的 next 方法, 指针指向第一数据成员。之后每次调用 next 方法都会将之后向后移动一个数据。
3. 知道遍历结束。
我们实现一个数组的遍历器试试:
var arr = [1, 3, 6, 5, 2];
var it = makeIterator(arr);
console.log(it.next()); //Object {value: 1, done: false}
console.log(it.next()); //Object {value: 3, done: false}
console.log(it.next()); //Object {value: 6, done: false}
console.log(it.next()); //Object {value: 5, done: false}
console.log(it.next()); //Object {value: 2, done: false}
console.log(it.next()); //Object {value: undefined, done: true}
function makeIterator(arr){
var nextIndex = 0;
return {
next: function(){
return nextIndex < arr.length ?
{value: arr[nextIndex++], done: false} :
{value: undefined, done: true}
}
};
}
由这个例子我们可以看出以下几点:
-
迭代器具有 next() 方法, 用来获取下一元素
-
next() 方法具有返回值, 返回一个对象, 对象 value 属性代表下一个值, done 属性表示是否遍历是否结束
-
如果一个数据结构本身不具备遍历器, 或者自带的遍历器不符合使用要求, 请按此例格式自定义一个遍历器。
其实一个 id 生成器就很类似一个遍历器:
function idGen(){
var id = 0;
return {
next: function(){ return id++; }
};
}
var id = idGen();
console.log(id.next()); //0
console.log(id.next()); //1
console.log(id.next()); //2
//…
对于大多数数据结构, 我们不需要再像这样写遍历器函数了。因为他们已经有遍历器函数[Symbol.iterator]
, 比如Array.prototype[Symbol.iterator]
是数组结构的默认遍历器。
下面定义一个不完整(仅包含add()方法)的链表结构的实例:
function Node(value){
this.value = value;
this.next = null;
}
function LinkedList(LLName){
this.head = new Node(LLName);
this.tail = this.head;
}
var proto = {
add: function(value){
var newNode = new Node(value);
this.tail = this.tail.next = newNode;
return this;
}
}
LinkedList.prototype = proto;
LinkedList.prototype.constructor = LinkedList;
LinkedList.prototype[Symbol.iterator] = function(){
var cur = this.head;
var curValue;
return {
next: function(){
if(cur !== null){
curValue = cur.value;
cur = cur.next;
return {value: curValue, done: false}
} else {
return {value: undefined, done: true}
}
}
};
}
var ll = new LinkedList(“prime”);
ll.add(1).add(2).add(3).add(5).add(7).add(11);
for(let val of ll){
console.log(val); //依次输出 1, 2, 3, 5, 7, 11
}
注意, 如果遍历器函数[Symbol.iterator]
返回的不是如上例所示结构的对象, 会报错。
当然, 如果不不喜欢用for…of(应该鲜有这样的人吧), 可以用 while 遍历:
var arr = [1, 2, 3, 5, 7];
var it = arr[Symbol.iterator];
var cur = it.next();
while(!cur.done){
console.log(cur.value);
cur = it.next();
}
以下操作会在内部调用相应的 iterator:
-
数组的解构赋值
-
展开运算符
-
yield*
后面带有一个可遍历结构 -
for…of
-
Array.from() 将类数组对象转换为数组
-
Map(), Set(), WeakMap(), WeakSet() 等构造函数传输初始参数时
-
Promise.all()
-
Promise.race()
Generator 与遍历器
iterator 使用 Generator 实现会更简单:
var it = {};
it[Symbol.iterator] = function* (){
var a = 1, b = 1;
var n = 10;
while(n){
yield a;
[a, b] = [b, a + b];
n–;
}
}
console.log([…it]); //1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
当然, 以上代码还可以这样写:
var it = {
var a = 1, b = 1;
var n = 10;
while(n){
yield a;
[a, b] = [b, a + b];
n–;
}
}
}
console.log([…it]); //[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
遍历器对象的其他方法
以上的遍历器对象只提到了 next() 方法, 其实遍历器还有 throw() 方法和 return() 方法:
-
如果遍历终止(break, continue, return或者出错), 会调用 return() 方法
-
Generator 返回的遍历器对象具throw() 方法, 一般的遍历器用不到这个方法。具体在 Generator 中解释。
function readlineSync(file){
return {
next(){
if(file.isAtEndOfFile()){
file.close();
return {done: true};
}
},
return(){
file.close();
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:前端)
最后
资料过多,篇幅有限,需要文中全部资料可以点击这里免费获取前端面试资料PDF完整版!
自古成功在尝试。不尝试永远都不会成功。勇敢的尝试是成功的一半。
本涵盖了95%以上前端开发知识点,真正体系化!**
[外链图片转存中…(img-r4qHjamg-1713482675127)]
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:前端)
[外链图片转存中…(img-JbLW7fx0-1713482675127)]
最后
[外链图片转存中…(img-4B88Mzne-1713482675127)]
[外链图片转存中…(img-eRHiixs9-1713482675127)]
资料过多,篇幅有限,需要文中全部资料可以点击这里免费获取前端面试资料PDF完整版!
自古成功在尝试。不尝试永远都不会成功。勇敢的尝试是成功的一半。