组内第一次分享遗留问题解决

问题

  • for…in 和 for…of 迭代时的问题。
  • every()和some()方法为什么需要return? 原理是什么?
  • bable语法糖?

解答

1. for…in 和 for…of 遍历时的问题。

1.1 问题复现1
let obj = {
    a: 1,
    b: 2,
    c: 3
};
let arr = [1, 2, 3, 4, 5];

现有一个对象和一个数组,分别使用for..inarrobj进行遍历,使用for..ofarr进行遍历,让arr中每一项和obj中每一项的value值都加1。如下:

for (let key in obj) {
    obj[key] ++;
}
console.log(obj);

for (let key in arr) {
    arr[key] ++;
}
console.log(arr);

for (let item of arr) {
    item ++;
    console.log(item, arr);
}
console.log(arr);

1.使用for...inarrobj进行操作发现:

obj: {a: 2, b: 3, c: 4}
arr: [2, 3, 4, 5, 6]

是没问题的。

2.使用for...ofarr进行操作,控制台打印发现:
在这里插入图片描述
每一项都加1了,但是arr没改变。

为什么会出现这种问题?

查阅文档发现:可迭代协议

可迭代协议: 可迭代协议允许 JavaScript 对象定义或定制它们的迭代行为,例如,在一个 for..of 结构中,哪些值可以被遍历到。一些内置类型同时是内置可迭代对象,并且有默认的迭代行为,比如 Array 或者 Map,而其他内置类型则不是(比如 Object))。这里我们注意到Array和Map与Object的迭代行为是不一样的。

当一个对象需要被迭代的时候(比如被置入一个 for…of 循环时),首先,会不带参数调用它的 @@iterator 方法,然后使用此方法返回的迭代器获得要迭代的值。重点在于“返回一个用于在迭代中获得值的迭代器”。
可以看出:for...of 的本质是返回一个迭代器,迭代器在迭代过程中返回值,而不是直接访问元素,所以无法修改元素。

迭代器如何获取值:迭代器通过next()方法返回值,而不是指向地址,所以在for of 迭代中无法改变数组元素

//for ... of内部的实现
try{
	//将可遍历对象转换为遍历器
	let iter = arr[Symbol.iterator]()
	let i = ''
	while(i != undefined){
		i = iter.next().value
		console.log(i)
	}
}catch(e){
	console.log(e)
}

// [Symbol.iterator]接口
Object.prototype[Symbol.iterator] = function(){
		let self = this
		let index = 0
		let keys = Object.keys(this)
		return {
			next(){
				if(index<keys.length){
					return {
						value:self[keys[index++]],
						done:false
					}
			   }else{
					return {
						value:undefined,
						done:true	
					}
				}
			}
		}

}

let obj = {
name:'wl',
age:23,
job:'stu',
size:18
}

for(let i of obj){
console.log(i)
}

自定义自定义可迭代对象:

let myIterator = {
    next: function() {
    },
    [Symbol.iterator]: function*() {
        yield 1;
        yield 2;
        yield 3;
    }
};
console.log([...myIterator]); // [1, 2, 3]
1.2 问题复现2
let arr = [1, 2, 3, 4, 5];
let obj = {
    a: 1,
    b: 2,
    c: 3
};

在这里插入图片描述
根据测试发现,在循环内部直接对数组或者对象添加一个对象,是无法改变index下标的,使用普通的for循环或for...of也出现同样的情况,为何?

arr.a的时候相当于在原先的的数组上新增了一个对象。约等于arr.push(8),push进去一个对象,:javascript在循环的时候,去更改数组,是无法改变当前循环的数组的。换个火狐浏览器就可以看出来最后一行的打印是浏览器行为,别被蒙蔽了。

火狐下运行:
在这里插入图片描述
接下来测试一下push行为:
在这里插入图片描述
为什么用push(4)?push不进去呢?

push进去了,只不过执行for...in的时候,你的即时状态是arr[0, 1, 2, 3]
for inforEach都是快照遍历,不是链式遍历,运行时,你动态添加的影响不到这个index,index是在编译阶段就确定了{}中的行为,for循环次数从一开始就被初始的arr长度规定好了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值